Introduce *_network_meta() functions

Description

The get_metadata(), update_metadata(), delete_metadata(), and add_metadata() functions are abstracted well enough for posts, comments, and users that adding in wrappers for network meta is pretty straight forward.

The table we're pulling from is sitemeta, which is a bummer. While the functions are named *_network_meta(), we still end up passing site as a parameter to the wrapped function. As it stands, any filters available would still need to use site rather than network. There's a chance we can work around this with some logic on the underlying functions, but I didn't go that far yet.

Certain network meta likely has more consequence when removed. It may be worth protecting a few of the meta keys so that they are validated properly and are not deleted. See next point.

This may or may not belong as part of an overall Network strategy that includes better structure around what a WP_Network object looks like and requires. That thought probably belongs somewhere else. :)

Change History (56)

sitemeta isn't really a meta table for key/value pairs, but is the network equivalent to "options". Indeed, sitemeta is currently handled by get/add/update/delete_site_option(). What's the purpose of these when we already have a more options-like API?

sitemeta isn't really a meta table for key/value pairs, but is the network equivalent to "options". Indeed, sitemeta is currently handled by get/add/update/delete_site_option(). What's the purpose of these when we already have a more options-like API?

Well, when you put it that way... :) Chalk this one up to losing my mind when wrapping it around historical naming.

Transients still call the old _network_options() functions to keep filters intact

Transients still use the same old cache group

The site-options cache group is in use by a bunch of things that aren't actually options, so it remains untouched and unaltered for this patch

Unit tests pass for me, but failed the first time I ran them. I'm not sure why, because the restapi test group is causing out-of-memory issues on my MacBook out-of-nowhere, and I can't complete the entire suite. (I can run this on my Pro later and figure it out.)

Patch looks good regarding the Meta API. I found only two issues with the network option implementation:

In get_network_option(), the call should be get_network_meta( $network_id, $option ) instead of get_network_meta( $network_id, $option, $default ). The resulting array should then be checked for its first value. If that exists, we have a match, otherwise the option is not set and we need to return the default. It would be nice if we could use get_network_meta( $network_id, $option, true ), but that's not possible since that function returns an empty string if no value is found which does not allow us to differentiate between "empty value set" vs "no value found". See @spacedmonkey's patch on #37181. We can also move the $default_site_option_{$option} filter below that to only run it if we actually need to return the default.

In add_network_option() let's use add_network_meta( $network_id, $option, $value, true ) to make sure these values are unique.

ms-functions.php needs to be included earlier, because the new _network_meta() functions live there

meta.php needs to be included earlier, so get_network_option() can get the site_name data from ms-settings.php

formatting.php needs to included earlier, because the meta-data API uses sanitize_key()

This looks scarier than it actually is.

None of the functions in these (or the surrounding) files are pluggable

The include-order in wp-settings.php is a mine-field anyways

It's a Christmas miracle we haven't had any problems including ms-blogs.php before ms-functions.php

Since meta is a thing that primary objects interact with, I'm OK making it available sooner, and if this turns out to be a mistake for some reason, there's no way for plugins or themes to get in this early anyways

Visiting the Network Plugins screen will cause the recently_activated meta key to be re-added 1 time for every refresh of the page

Broken logic in the plugins list table class causes the above bug, and using the meta-data API (instead of relying on the alloptions cache) exposes it

Fixing the above broken logic is easy, and maybe should be its own separate ticket, but it's pretty critical that get fixed along with this, so I've lumped it in, which I think is safe to do since it's documented accordingly here and in the code

The meta api current supports storing multiple rows in one key. However network options do not support it. There could be issues with using the meta functions do write multiple rows then never being able to get the out the db. This work around allows for all the items to be received but the first is used.

I did a little work on profiling this patch. The biggest change to performance is the function wp_load_core_site_options.
Instead of loading on a 9 of core options, it now loads all of network options on page load. On average the standard wordpress install has 31 rows in the network meta table. However, loading all the network options, doesn't mean now queries, it just means one query that gets more rows. Loading all network meta might be a problem if there are plugins that add lots of network options.

If object caching is enabled, there is a possible effect on performance. Before only the core keys were loaded on page load. Now, that all the keys are loaded, it means that the admin terminal is faster and there are less SQL queries.

There is no right answer here, I am just saying this change is going to have an effect, for some positive and for some negative.

I uploaded a new set of patches - set as I have splitted the network meta API introduction (see 25344.10.network-meta.diff​) from its implementation in the *_network_option() functions (see 25344.10.network-options.diff​), to have a better overview and to be able to later commit them separately (that does not imply I'm wary of any of the two parts). Be aware that the network options patch relies on the network meta patch in order to work.

Remove the fix in src/wp-includes/meta.php as that does not belong into this patch, but into a patch on #38203.

Bust network query cache when network meta is added/updated/deleted.

Introduce meta query functionality for WP_Network_Query. Meta query functionality is only available if the class has already been loaded; that means that no meta queries are supported in sunrise.php at the moment. We can revisit after figuring out loading order of files (see below).

Move the *_network_meta() functions into src/wp-includes/ms-blogs.php. The names of the two files (ms-blogs.php and ms-functions.php) are really confusing, but all basic site and network functionality resides in ms-blogs.php for now, and questioning that belongs into another ticket IMO (although it's probably worth doing that at some point). This also makes the patch more clear and reduces chances for unexpected bugs, as we don't need to change the loading order of files. It's certainly sub-optimal that meta.php is loaded after some other stuff that relies on it, but this happens in a broader scope - again, that belongs into another ticket I think. I don't like to clutter this patch here with such things, so maybe we should open a ticket to rethink the multisite file structure in general, and then adjust this patch after we have figured that out.

I didn't change anything in 25344.10.network-options.diff​. However, that patch currently does not work because of the loading order that we need to discuss (so here it is critical, see above). Functionality-wise, I don't see anything we need to change in the patch. Once we get it back to work, we of course need to verify through unit tests.

I resubmitted my patch with tests. I did forget to add the file into my patch. I agree we should break this into smaller patches so make it easier to merge. I think we should keep on talk of a meta query in #38025 as adding a meta query is really unrelated to implementing the meta api.

After working on #37181 ticket for a while, I have spotted an issue with adding these functions. sanitize data. Currently the network options allow for sanitize data to be used in them. This could be a object you want to cached. But the meta api out of the box doesn't handle this. In #37181 I handle this inside the *_network_option functions, for compatiblity. But this may mean we may never to able to put these functions in core.

As discussed at WordCamp US, we will not introduce *_network_meta() functions at this point, this should remain plugin territory. Our network meta efforts in core should be limited to using it internally in the *_network_option() functions (see #37181).