Make WordPress Core

Opened 7 years ago

Last modified 21 months ago

#39286 new enhancement

Standardizing actions and filters for adding, getting, setting, updating, and deleting options and transients

Reported by: nathanatmoz's profile NathanAtmoz Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Options, Meta APIs Keywords:
Focuses: Cc:

Description

The Problem

In a nutshell, the problem is that there is no standardization of hooks surrounding the options and transient APIs and the hooks presently available are inconsistent in their terminology.

Issue 1: Add Option

When adding an option to the database, there are presently 3 hook available:

  • add_option
  • add_option_{$option}
  • added_option

There are two main points of confusion:

  • The first point of confusion is that add_option is fired before the option is added to the database, but add_option_{$option} is fired after the option is added.
  • The second is that prior to the option being added to the database, there is a hook available that will fire anytime an option is added, while there are two hooks fired after the option is added. There is no hook available prior to the option being added to the database that fires for the specific $option.

These same two issues are present for updating and deleting options.

Issue 2: Get Option

When getting an option from the database, there are only two hooks fired:

  • pre_option_{$option}
  • option_{$option}

The first is fired before the option is getted from the database and the second after. The problems are that:

  • Unlike adding, updating, and deleting, there is no verb in this hook to tell what is being done
  • There are no hooks that fire for every option getted from the database

Issue 3: Delete Transient

Transients are sort of like options. Without an external object cache, WordPress stores them in the options table of the database. It would make sense that the hooks available for transients are consistent with those available for options. If we look at deleting a transient, there are two hooks available:

  • delete_transient_{$transient}
  • deleted_transient

( The same issues are present with site transients. )

Remembering issue 1 above, there are presently three hooks available when deleting and option.

  • delete_option
  • delete_option_{$option}
  • deleted_option

There are a couple issues:

  • There is no hook present that will fire every time a transient is deleted, either before or after
  • The delete_transient_{$transient} is fired BEFORE the transient is deleted in contrast with the delete_option_{$option} hook which is fired AFTER the option is deleted.

Issue 4: Pre

Prior to getting and setting transients, the hooks all start with pre_. But this prefix is used inconsistently throughout.

  • It is not used prior to deleting the transient
  • It is used prior to getting an option, but not prior to adding, updating or deleting

Proposal

Structure of hooks

I would like to propose that there be four hooks for each action: two before and two after, one general and one specific. The general structure would look like so:

"pre_{present-tense-verb}_{noun}"
"pre_{present-tense-verb}_{noun}_{$variable}"
[verb noun]
"{past-tense-verb}_{noun}_{$variable}"
"{past-tense-verb}_{noun}"

So for instance, adding an option would look like:

"pre_add_option"
"pre_add_option_{$variable}"
[add option]
"added_option_{$variable}"
"added_option"

Type of hook

Prior to adding, setting, or updating options/transients, the hooks should be a filter to allow changing of the option/transient prior to writing to the database. After adding, setting, or updating the hooks should be an action since the write has already occurred.

Both prior and after getting an option/transient, the hook should be a filter. I'm not sure the use case for filtering the option before running the query, but that's what's presently done.

Before and after the option is deleted the hook should be an action as there's no need to change the value of the option since it's being deleted anyway.

Deprecating hooks

There are several hooks no present that don't fit the proposed structure above. I suggest these hooks continue to work for backward compatibility, but that they be deprecated.

See also

Google Doc showing all the new and deprecated hooks

Related Tickets

Change History (1)

#1 @johnjamesjacoby
21 months ago

Consistent patterns make for happy developers, and I am in agreement with you here @NathanAtmoz. These functions and their hooks are an opportunity for improvement that I have personally experienced myself multiple-multiple times. I always end up digging into the code to make sure I'm using the right hooks in the right ways.

I do not feel strongly about the pre_, post_, or present/past tenses for hook naming. before & after are also sometimes used (and probably are my preference these days) because they remove ambiguity with "post" which is used all over the place for other things. (I know you didn't suggest post_ here, but it goes along with pre_ so I'm just mentioning it for the sake of...)

The other thing that crosses my mind (once we start wanting to create a pattern for calling multiple hooks in a consistent way) is if this may also be an opportunity to redefine the problem and determine if a new API makes sense to encapsulate the routine code being written, or at least solidly eliminate that possibility. Let's not use the actions & filters APIs only because they already exist, and make sure they are the correct or best approach. And/or, is it DRY'able, etc...

Thanks @NathanAtmoz for this first ticket of yours. I know it's a few years old now, but it is on my mind!

Note: See TracTickets for help on using tickets.