92 lines
5.9 KiB
Markdown
92 lines
5.9 KiB
Markdown
# Hooks and integration
|
|||
|
|
|
||
|
|
What Nolimit Cache offers to other code, and what it listens to. Written for
|
||
|
|
developers who want to extend the plugin or sit next to it; nothing here is
|
||
|
|
needed to use it.
|
||
|
|
|
||
|
|
Hooks prefixed `nlcac_` are this plugin's own and are stable: a rename is a
|
||
|
|
breaking change and will be called out in the release notes. Hooks prefixed
|
||
|
|
`wpmgr_` are shared by name with the other Nolimit plugins (see section 2).
|
||
|
|
|
||
|
|
A note on the words: for a filter, `add_filter()` is how you **answer** it, by
|
||
|
|
supplying a value. The headings below describe the mechanism, who calls
|
||
|
|
`apply_filters()` and who calls `add_filter()`, because that cannot be misread.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. Extension points this plugin OFFERS — `nlcac_*`
|
||
|
|
|
||
|
|
`apply_filters()` / `do_action()` in our code: we run everyone's callbacks.
|
||
|
|
|
||
|
|
| Hook | Type | Signature | Fired from |
|
||
|
|
|---|---|---|---|
|
||
|
|
| `nlcac_reason_not_to_cache` | filter | `( string $reason, … )` — return a non-empty string to refuse to cache this request | page cache |
|
||
|
|
| `nlcac_page_cached` | action | `( string $path )` — a page was just written to disk | page cache |
|
||
|
|
| `nlcac_purge_urls_for_post` | filter | `( array $urls, int $post_id )` — the URLs about to be purged for a post | purging |
|
||
|
|
| `nlcac_preload_urls` | filter | `( array $urls )` — the queue the preloader will walk | preloader |
|
||
|
|
| `nlcac_exclude_script` | filter | `( bool $exclude, string $handle )` — keep a script out of defer | optimiser |
|
||
|
|
| `nlcac_ai_payload` | filter | `( array $payload )` — what the assistant is about to send | assistant |
|
||
|
|
| `nlcac_images_skip` | filter | `( bool $skip, string $img_tag )` — return true to keep one `<img>` out of the WebP/AVIF rewrite | images |
|
||
|
|
|
||
|
|
**If this plugin is absent**, none of these fire. A consumer must not assume
|
||
|
|
its callback ever runs; `has_filter()` is not a substitute for the plugin
|
||
|
|
being active.
|
||
|
|
|
||
|
|
**A consumer must not** do slow or networked work in
|
||
|
|
`nlcac_reason_not_to_cache`. It runs on every request, before WordPress, in
|
||
|
|
the drop-in — which is the whole reason the cache is fast.
|
||
|
|
|
||
|
|
## 2. The family's shared hooks — `wpmgr_*`
|
||
|
|
|
||
|
|
Shared by name across the Nolimit plugins, so **load order decides who wins**
|
||
|
|
for anything that declares itself once.
|
||
|
|
|
||
|
|
### Offered here — we call `apply_filters()` / `do_action()`
|
||
|
|
|
||
|
|
| Hook | Type | Notes |
|
||
|
|
|---|---|---|
|
||
|
|
| `wpmgr_cache_cleared` | action | `( int $removed )`. Fired when the page cache is emptied, so a sibling holding derived state can drop it in the same click. Our own object cache listens to it and only calls `wp_cache_flush()`, so there is no path back into purge. |
|
||
|
|
| `wpmgr_dashboard_cards` | filter | Provided by the shared menu file, which every Nolimit plugin carries identically. |
|
||
|
|
| `wpmgr_menu_title` | filter | Same. |
|
||
|
|
| `wpmgr_menu_glyph` | filter | Same. It exists so the glyph can be overridden. |
|
||
|
|
|
||
|
|
### Answered here — we register a callback with `add_filter()` / `add_action()`
|
||
|
|
|
||
|
|
| Hook | Type | What we do | If nobody offers it |
|
||
|
|
|---|---|---|---|
|
||
|
|
| `wpmgr_dashboard_cards` | filter | Add this plugin's card | The card is not drawn; nothing breaks |
|
||
|
|
| `wpmgr_menu_title` | filter | Answer the shared menu's title | Shared file's default |
|
||
|
|
| `wpmgr_cache_cleared` | action | Flush our object cache | — (we also fire it) |
|
||
|
|
| `wpmgr_signals` | filter | Supply this plugin's health signals to a family-wide collection. We answer it; we never read it | Only Nolimit Assistant applies this filter. With it absent or inactive, our signals are contributed to nothing and no error is raised. |
|
||
|
|
| `wpmgr_setup_recommendations` | filter | Offer three setup items to the Assistant's Setup screen: turn the page cache on, warm it in the background, keep the basket rule on. Every `done` is read from the stored setting, never measured. | Nothing is offered and nothing breaks. Only Nolimit Assistant applies this filter, so without it these items are shown nowhere |
|
||
|
|
|
||
|
|
## 3. WordPress and WooCommerce core
|
||
|
|
|
||
|
|
The plugin also attaches to WordPress and WooCommerce core hooks. They are
|
||
|
|
listed by area rather than one row each, because none of them is a contract
|
||
|
|
anyone else needs to honour: they are how the plugin attaches to WordPress.
|
||
|
|
|
||
|
|
| Area | Hooks |
|
||
|
|
|---|---|
|
||
|
|
| Boot | `init`, `plugins_loaded` |
|
||
|
|
| Admin | `admin_init`, `admin_menu`, `admin_notices`, `admin_head`, `admin_footer`, `admin_bar_menu`, `admin_enqueue_scripts`, `plugin_action_links_{file}` |
|
||
|
|
| Purging | `transition_post_status`, `post_updated`, `deleted_post`, `edit_term`, `delete_term`, `comment_post`, `transition_comment_status`, `update_option_sidebars_widgets`, `shutdown` |
|
||
|
|
| Front end | `template_redirect`, `wp_head`, `wp_enqueue_scripts`, `script_loader_tag`, `script_loader_src`, `style_loader_src`, `the_content`, `wp_get_attachment_url`, `wp_calculate_image_srcset`, `embed_oembed_discover`, `tiny_mce_plugins` |
|
||
|
|
| Updates | `site_transient_update_plugins`, `plugins_api`, `upgrader_process_complete` |
|
||
|
|
| Media | `wp_update_attachment_metadata`, `wp_delete_file` |
|
||
|
|
| Settings | `update_option_nlcac_settings` |
|
||
|
|
| Scheduling | `cron_schedules` |
|
||
|
|
| REST | `rest_api_init` |
|
||
|
|
| WooCommerce | `woocommerce_new_product`, `woocommerce_update_product`, `woocommerce_order_status_changed`, `woocommerce_product_set_stock`, `woocommerce_product_set_stock_status`, `woocommerce_variation_set_stock`, `woocommerce_variation_set_stock_status`, `wc_after_products_starting_sales`, `wc_after_products_ending_sales` |
|
||
|
|
|
||
|
|
🔴 **`site_transient_update_plugins` is the dangerous one.** The filter name
|
||
|
|
is built from the update host, so every plugin updating from
|
||
|
|
gitea.nolimit.dk lands on the same one and WordPress runs every callback for
|
||
|
|
every plugin. Answering unconditionally offers our zip to a sibling. The
|
||
|
|
guard is two halves and both are required — register with **3** arguments,
|
||
|
|
and return `$update` untouched unless `$plugin_file` is ours. Registering
|
||
|
|
with 2 leaves the argument unset and the guard silently does nothing, which
|
||
|
|
is the same shape of bug it exists to fix.
|
||
|
|
|
||
|
|
If you write a plugin that updates from the same host, apply the same guard.
|