Download the PHP package conduit/gorilla-claw without Composer
On this page you can find all versions of the php package conduit/gorilla-claw. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package gorilla-claw
GorillaClaw
WordPress action / filter runtime toolkit library, with monkey-patching capabilities.
- Locate - Easily find hook handlers, by filter, function name, object name and method
- Replace - Replace hook callbacks in one line, even use the original callback's
$this
via magic scope binding - Rebind - Add new handlers, bound to another's scope (see 'rebind')
- Inject - Inject pre and post processors to existing handlers, with scope binding
- Manage hook handlers as a collection
add_filters()
andadd_actions()
for attaching to multiple hooks in a single command- Uses fast Closures, not slow Reflection.
- [Coming Soon] Profile individual handlers, or the entire hook
The intention is that this library will be safe to use in production, with minimal performance overhead. However, until the 1.0.0
release, this should only be used for testing. But there is already full test coverage for releases.
Installation
Via composer
:
What is this?
GorillaClaw is a runtime toolkit library for manipulating WordPress hooks; aka. actions and filters. It's intended to help end-user developers make plugins work with each other when conflicting or misbehaving.
It should not be used as a component in a distributed WordPress plugin, use the normal WordPress Hook API for that. It also isn't intended as a 'new sparkly hook wrapper', that nobody needs or wants.
A unique feature of GorillaClaw is that it automatically binds your hook handlers to existing (and previously uncontrollable) objects that may lay nestled in another plugin's code, by monkey-patching scope. It even breaks into private
and protected
properties, and it also allows you to call any method, with likely disasterous consequences.
:warning: Here start the warnings. They're deliberately peppered throughout.
:warning: Ignore them at your peril.
As well as the dangerous features, the library contains some useful functionality for locating handlers and replacing or removing them (safely).
GorillaClaw can be used for good. It can also be used for evil.
Locating
Danger Level: :dark_sunglasses: Safe
Find handlers using a number of different queries. Easily locate specific classes of handler.
find_filters()
returns a collection of Hook
s, which is the basis for all hook manipulation in GorillaClaw.
Removal
Danger Level: :dark_sunglasses: Safe
Un-hook / remove handlers found with find_*****s()
. Safe and simple.
Replacement
Danger Level: :thinking: Be careful
OK, here's where it starts to get sketchy. We can replace
handlers with our own closures, but magically, $this
will be proxied to the original object. We can even read and write protected or private properties, and call methods similarly.
:warning: Properties are writeable, even if
protected
orprivate
orfinal class
.:warning: Methods called by the replaced handler may change object state for subsequent calls for this action or others relying on the original object. This can cause unpredictable behaviour in most cases.
Lots of headaches will most likely occur if you change the class state in some way. Although in extreme cases, this is desired. If you can in anyway avoid doing this, avoid it.
The actual mechanism of doing this is quite unusual, using Closure
and scope binding and passing by reference. No slow Reflection
is used.
Rebinding
Danger Level: :warning: Probably a bad idea
Rebinding is similar to replacement, except the original filter handler is left active. This allows us to 'tap-in' to an existing filter handler's $this
and scope.
:warning: Methods called by the re-bound handler may change object state for subsequent calls for this action or others relying on the original object. This can cause unpredictable behaviour in most cases.
:warning: Rebinding can not guarantee the order in which the re-bound function and the original execute. That's entirely down to the application logic. As the objects are linked, both handlers can affect each other.
:thinking: Setting up and tearing down modifications to an object on a re-bound handler using Injection can mitigate some of the risks above.
Injection
Danger Level: :warning: Probably a bad idea
Injection allows you to add functions executed before and after a single filter handler. You may access $this
and even modify private variables.
Most of the time, if we want a function to run before an existing handler, we just add it with a 'lower' priority number, and 'higher' to run after. This is the right way. However, some times we just want to manipulate a single handler, like maybe ...ugh.. call methods that change the object state, so it makes sense to modify -> run the original -> un-modify
, so future interactions with the object remain unaffected.
Both before and after callbacks are optional, and feed through their arguments and return values in the usual chained WordPress way.
:warning: Methods called by the injected handlers may change object state for subsequent calls for this action or others relying on the original object. Remember to tear down modifications to minimise the chance of this occuring.
:warning: Rebinding can not guarantee the order in which the re-bound function and the original execute. That's entirely down to the application logic. As the objects are linked, both handlers can affect each other.
Adding
There is also a simple wrapper around add_filter()
and add_action()
- plural versions allowing handlers to be added to multiple actions / filters in one line. It's just syntactic sugar.
You don't need this
Ideally, you should never 'need' this library.
However, with plugin developers making use of objects more frequently (good!), and not always being mindful of scope limitations (bad), you can sometimes need to patch-in to a plugin object's scope and work with private variables / methods. Some examples of this include plugins that set up Gutenberg Blocks, and plugins that use dependency injection.
If you can achieve your goal without this library, then do that instead.
Runtime monkey-patching can cause a whole load of debugging hassle if done incorrectly, so please be very careful if modifying object properties whether using replace
, rebind
or inject
.
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
License
Turn off your linters, throw away your test suite, encrypt your codebase! It's time to break shit...