Is there a concise, usual way of extracting theme and plugin versions
into a config file such as .wp-env.json or composer.json without
having direct access to the database?
I assumed there existed a .wp-env.json
generator, but I couldn’t find it. That might help if available.
There are tons of ways to clone a site, but let’s assume we only want to get a basic auto-generated .wp-env.json
info directly from the main site.
Not sure if it’s useful but here’s a skeleton of a plugin that assumes only plugins and themes hosted on wordpress.org:
<?php
/**
* Plugin Name: WPSE-407466 - REST endpoint for basic wp-env info
* Version: 0.0.1
*/
add_action( 'rest_api_init', function() {
register_rest_route(
'wpse/v1',
'/wp-env/',
array(
'methods' => 'GET',
'permission_callback' => function () {
return current_user_can( 'manage_options' );
},
'callback' => function( $request ) {
$active_plugins = (array) get_option( 'active_plugins', array() );
$data = array();
foreach( $active_plugins as $plugin ) {
$data['plugins'][] = 'WordPress/' . dirname( $plugin );
}
$data['themes'] = 'WordPress/' . get_stylesheet();
$data['core'] = 'WordPress/WordPress#' . get_bloginfo( 'version' );
// phpVersion only supports x.y not x.y.z
$data['phpVersion'] = sprintf( "%s.%s", PHP_MAJOR_VERSION, PHP_MINOR_VERSION );
return $data;
},
)
);
} );
A GET request (with a wp-rest nonce or application password) on:
https://example.com/wp-json/wpse/v1/wp-env
as logged in user with manage_options
capability will output something like:
{
"plugins": [
"WordPress/buddypress",
"WordPress/jetpack"
],
"themes": [
"WordPress/neve"
],
"core": "WordPress/WordPress#5.9.3",
"phpVersion": "7.4"
}
but note that this is not tested yet with wp-env, just used
https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/
as a guidance.
Here’s an example using the application password:
curl --user "USERNAME:APPLICATION-PASSWORD" "https://HOSTNAME/wp-json/wpse/v1/wp-env"
where we replace USERNAME
, APPLICATION-PASSWORD
and HOSTNAME
.
Download link formulas
Let’s add the versions for plugins and themes to generate download links.
If we only have wordpress.org hosted plugins and themes and if we assume they follow this download link formula:
https://downloads.wordpress.org/plugin/<PLUGIN-SLUG>.x.y.z.zip
https://downloads.wordpress.org/theme/<THEME-SLUG>.x.y.z.zip
Then we can update the plugin:
/**
* Plugin Name: WPSE-407466 - REST endpoint for basic wp-env info
* Version: 0.0.2
*/
add_action( 'rest_api_init', function() {
register_rest_route(
'wpse/v1',
'/wp-env/',
array(
'methods' => 'GET',
'permission_callback' => function () {
return current_user_can( 'manage_options' );
},
'callback' => function( $request ) {
if ( ! function_exists( 'get_plugins' ) ) {
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}
$active_plugins = (array) get_option( 'active_plugins', array() );
$installed_plugins = get_plugins();
$data = array();
foreach( $active_plugins as $plugin ) {
$data['plugins'][] = sprintf(
'https://downloads.wordpress.org/plugin/%s.%s.zip',
dirname( $plugin ),
$installed_plugins[$plugin]['Version']
);
}
$data['themes'][] = sprintf(
'https://downloads.wordpress.org/theme/%s.%s.zip',
get_stylesheet(),
wp_get_theme()->Version
);
$data['core'] = 'WordPress/WordPress#' . get_bloginfo( 'version' );
// phpVersion only supports x.y not x.y.z
$data['phpVersion'] = sprintf( "%s.%s", PHP_MAJOR_VERSION, PHP_MINOR_VERSION );
return $data;
}
)
);
} );
with output like:
{
"plugins": [
"https://downloads.wordpress.org/plugin/buddypress.10.3.0.zip",
"https://downloads.wordpress.org/plugin/jetpack.10.9.1.zip"
],
"themes": [
"https://downloads.wordpress.org/theme/neve.2.9.2.zip"
],
"core": "WordPress/WordPress#5.9.3",
"phpVersion": "7.4"
}
REST endpoint for plugins
There is also a way to extract info on the active plugins from the plugins REST endpoint.
Here’s an example using the application password:
curl --user "USERNAME:APPLICATION-PASSWORD" "https://HOSTNAME/wp-json/wp/v2/plugins/?status=active"
where we replace USERNAME
, APPLICATION-PASSWORD
and HOSTNAME
.
Example output:
[
{
"plugin": "jetpack/jetpack",
"status": "active",
"name": "Jetpack",
"plugin_uri": "https://jetpack.com",
"author": "Automattic",
"author_uri": "https://jetpack.com",
"description": {
"raw": "Security, performance, and marketing tools made by WordPress experts. Jetpack keeps your site protected so you can focus on more important things.",
"rendered": "Security, performance, and marketing tools made by WordPress experts. Jetpack keeps your site protected so you can focus on more important things. <cite>By <a href=\"https://jetpack.com\">Automattic</a>.</cite>"
},
"version": "10.9.1",
"network_only": false,
"requires_wp": "5.9",
"requires_php": "5.6",
"textdomain": "jetpack",
"_links": {
"self": [
{
"href": "https://example.com/wp-json/wp/v2/plugins/jetpack/jetpack"
}
]
}
},
... etc ...
]
This data could be used in a custom local script.
Get download links from api.wordpress.org
If the formulas above are not always working, then we could otherwise get actual download links from api.wordpress.org with a little more effort.
Here’s more on this wordpress.org API:
https://codex.wordpress.org/WordPress.org_API
The mock test in core had an informative link regarding API parameters.
Here’s the info on the JetPack plugin as an example:
https://api.wordpress.org/plugins/info/1.2/?action=plugin_information&request[slug]=jetpack
that will contain zip download links within the plugin’s version history:
versions: {
10.0: "https://downloads.wordpress.org/plugin/jetpack.10.0.zip",
10.1: "https://downloads.wordpress.org/plugin/jetpack.10.1.zip",
10.2: "https://downloads.wordpress.org/plugin/jetpack.10.2.zip",
10.2.1: "https://downloads.wordpress.org/plugin/jetpack.10.2.1.zip",
10.3: "https://downloads.wordpress.org/plugin/jetpack.10.3.zip",
10.4: "https://downloads.wordpress.org/plugin/jetpack.10.4.zip",
10.5: "https://downloads.wordpress.org/plugin/jetpack.10.5.zip",
10.5.1: "https://downloads.wordpress.org/plugin/jetpack.10.5.1.zip",
10.6: "https://downloads.wordpress.org/plugin/jetpack.10.6.zip",
10.7: "https://downloads.wordpress.org/plugin/jetpack.10.7.zip",
10.8: "https://downloads.wordpress.org/plugin/jetpack.10.8.zip",
10.9: "https://downloads.wordpress.org/plugin/jetpack.10.9.zip",
10.9.1: "https://downloads.wordpress.org/plugin/jetpack.10.9.1.zip",
11.0: "https://downloads.wordpress.org/plugin/jetpack.11.0.zip",
11.1: "https://downloads.wordpress.org/plugin/jetpack.11.1.zip",
11.1-a.1: "https://downloads.wordpress.org/plugin/jetpack.11.1-a.1.zip",
11.1-a.3: "https://downloads.wordpress.org/plugin/jetpack.11.1-a.3.zip",
11.1-a.5: "https://downloads.wordpress.org/plugin/jetpack.11.1-a.5.zip",
11.1-beta: "https://downloads.wordpress.org/plugin/jetpack.11.1-beta.zip",
11.1-beta2: "https://downloads.wordpress.org/plugin/jetpack.11.1-beta2.zip",
11.2-a.1: "https://downloads.wordpress.org/plugin/jetpack.11.2-a.1.zip",
...cut...
trunk: "https://downloads.wordpress.org/plugin/jetpack.zip"
},
It’s possible to reduce the size of the response by turning off fields with request[fields][<FIELD>]=0
.
As an example let’s turn off the fields for contributors, sections, screenshots, tags, rating and banners:
with the output:
{
name: "Jetpack – WP Security, Backup, Speed, & Growth",
slug: "jetpack",
version: "11.1",
author: "<a href="https://jetpack.com">Automattic</a>",
author_profile: "https://profiles.wordpress.org/automattic/",
requires: "5.9",
tested: "6.0",
requires_php: "5.6",
rating: 78,
num_ratings: 1778,
support_threads: 248,
support_threads_resolved: 218,
active_installs: 5000000,
last_updated: "2022-07-05 3:29pm GMT",
added: "2011-01-20",
homepage: "https://jetpack.com",
download_link: "https://downloads.wordpress.org/plugin/jetpack.11.1.zip",
versions: {
10.0: "https://downloads.wordpress.org/plugin/jetpack.10.0.zip",
10.1: "https://downloads.wordpress.org/plugin/jetpack.10.1.zip",
10.2: "https://downloads.wordpress.org/plugin/jetpack.10.2.zip",
10.2.1: "https://downloads.wordpress.org/plugin/jetpack.10.2.1.zip",
10.3: "https://downloads.wordpress.org/plugin/jetpack.10.3.zip",
10.4: "https://downloads.wordpress.org/plugin/jetpack.10.4.zip",
10.5: "https://downloads.wordpress.org/plugin/jetpack.10.5.zip",
10.5.1: "https://downloads.wordpress.org/plugin/jetpack.10.5.1.zip",
10.6: "https://downloads.wordpress.org/plugin/jetpack.10.6.zip",
10.7: "https://downloads.wordpress.org/plugin/jetpack.10.7.zip",
10.8: "https://downloads.wordpress.org/plugin/jetpack.10.8.zip",
10.9: "https://downloads.wordpress.org/plugin/jetpack.10.9.zip",
10.9.1: "https://downloads.wordpress.org/plugin/jetpack.10.9.1.zip",
11.0: "https://downloads.wordpress.org/plugin/jetpack.11.0.zip",
11.1: "https://downloads.wordpress.org/plugin/jetpack.11.1.zip",
11.1-a.1: "https://downloads.wordpress.org/plugin/jetpack.11.1-a.1.zip",
11.1-a.3: "https://downloads.wordpress.org/plugin/jetpack.11.1-a.3.zip",
11.1-a.5: "https://downloads.wordpress.org/plugin/jetpack.11.1-a.5.zip",
11.1-beta: "https://downloads.wordpress.org/plugin/jetpack.11.1-beta.zip",
11.1-beta2: "https://downloads.wordpress.org/plugin/jetpack.11.1-beta2.zip",
11.2-a.1: "https://downloads.wordpress.org/plugin/jetpack.11.2-a.1.zip",
...cut...
trunk: "https://downloads.wordpress.org/plugin/jetpack.zip"
},
donate_link: ""
}
Similar for the themes.
Hopefully this can help you to generate your own local config files.