Make WordPress Core

Opened 2 years ago

Last modified 12 months ago

#56221 accepted enhancement

Add download URL to plugins REST create (install) endpoint

Reported by: brianhenryie's profile brianhenryie Owned by: timothyblynjacobs's profile TimothyBlynJacobs
Milestone: Future Release Priority: normal
Severity: normal Version: 5.5
Component: Plugins Keywords: needs-testing has-unit-tests has-patch dev-feedback
Focuses: administration, rest-api Cc:


The wp-json/wp/v2/plugins endpoint allows installing plugins by POSTING the slug parameter. It then queries the .org plugin repo for the download link and proceeds to download and install that zip file using Plugin_Upgrader.

I would like to be able to specify the download URL so I can install plugins from outside the .org plugin repo.

My plan is to install plugins to my site when a I create a new release on GitHub, i.e. use GitHub Actions to POST the new download URL to my site, then serve the plugin to other sites using SatisPress.

I tried unsuccessfully to find past related tickets that maybe discussed if omitting this functionality was intentional.

It looks like a relatively easy change. I'll make PR for it soon.

Change History (15)

#1 @brianhenryie
2 years ago

  • Summary changed from Add download URL to plugins REST endpoint to Add download URL to plugins REST create (install) endpoint

#2 @TimothyBlynJacobs
2 years ago

  • Severity changed from minor to normal
  • Version set to 5.5

Hi @brianhenryie,

Thanks for the ticket and welcome to Trac!

This was intentionally omitted in the first pass of the endpoint. The thinking was that if there were issues with the endpoint it would limit potential damage by only allowing vetted plugins to be installed onto the site.

Now that we're two years out from the endpoint landing in WP 5.5, I think we can consider opening the endpoint up more to allow installing custom plugins.

Cc: @spacedmonkey, @peterwilsoncc.

This ticket was mentioned in PR #3515 on WordPress/wordpress-develop by @brianhenryie.

20 months ago

  • Keywords has-patch has-unit-tests added

#4 follow-up: @brianhenryie
20 months ago

  • Keywords needs-testing dev-feedback added
  • Severity changed from normal to minor

Tests are passing, so it's probably good to merge!


  1. There seems to be no way to require one-of-two parameters. See [WP_REST_Request::has_valid_params()]( where $arg['required'] is a bool.

I looked at using validate_callback but it is invoked per parameter, i.e. if both are missing, it is never called, so it can't impose a "one of these must be present" requirement.

The test case I rough-worked (not committed) did fail as it should, anyway.

  1. I couldn't find a .tar plugin on .org to validate the non-zip scenario.

#5 @brianhenryie
20 months ago

  • Severity changed from minor to normal

#6 @brianhenryie
20 months ago

Now I think more... in WP_REST_Plugins_Controller::create_item where I have if ( isset( $request['url'] ) ) { ... else, it should be an elseif ( isset( $request['slug'] ) ) { followed by something like } else { $response = new WP_REST_Response( null, 400 );

I hadn't realised that was another avenue into the REST input validation. I'll have a think about it.

#7 @brianhenryie
20 months ago

Also, I created my own regex to validate a URL.

Maybe there's a WordPress standard one that this should be closer to.

#8 in reply to: ↑ 4 @TimothyBlynJacobs
20 months ago

Replying to brianhenryie:

I looked at using validate_callback but it is invoked per parameter, i.e. if both are missing, it is never called, so it can't impose a "one of these must be present" requirement.

You can set a validate_callback at the route-level now alongside callback and args.

#9 @brianhenryie
20 months ago

I added the validate_callback, and made it such that one of slug or url are required, and if both are present, the url must be a download URL. Then during the actual install function, it will pull the language pack as specified in the slug, and install the plugin from the URL, which would possibly be an older version of the plugin.

There's definitely room for people to do weird stuff like mismatching a slug and plugin. And arguing in the other direction, it would be valid for me to modify a .org plugin, host it somewhere else, and want the .org language pack while installing it.

#10 @brianhenryie
20 months ago

I would also like to be able to POST a zip file to the site to be installed. I make heavy use of WP CLI dist-archive-command in my dev workflow, where there is no public URL to the generated .zip.

Is it OK to edit this ticket's title and introduction, then continue adding to the patch I've been working on?

#11 @brianhenryie
19 months ago

I have POSTing the .zip file to the API working (according to my unit tests at least, I haven't run live tests yet).

It builds on the work for this here, particularly in validate_callback.

I can merge it into the PR here for review, or wait until that is approved and open a new ticket. Let me know.

#12 @TimothyBlynJacobs
17 months ago

  • Milestone changed from Awaiting Review to 6.3
  • Owner set to TimothyBlynJacobs
  • Status changed from new to accepted

Let's take a look at this for 6.3

#13 @oglekler
12 months ago

@TimothyBlynJacobs can you please take a look at this ticket. We are in 9 days until Beta 1. So, if this enhancement is ready, it can go into trunk, if not - it should to be moved to 6.4. Thank you 🙏

This ticket was mentioned in Slack in #core by mukeshpanchal27. View the logs.

12 months ago

#15 @oglekler
12 months ago

  • Milestone changed from 6.3 to Future Release

This ticket was discussed during the bug scrub.
Because there is no progress in this ticket, and Beta 1 is planned for today, it was decided to move this ticket into Future release.

Note: See TracTickets for help on using tickets.