Installing WP plugins via Composer

 _       ______     ______
| |     / / __ \   / ____/___  ____ ___  ____  ____  ________  _____
| | /| / / /_/ /  / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
| |/ |/ / ____/  / /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
|__/|__/_/       \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
									 /_/

In this article, we will talk about how to install plugins via composer. The instructions will cover plugins that are in the WP repository and plugins that are developed on github.com and added to the default PHP package directory https://packagist.org/.

For plugins from the WP repository, there is a separate repository https://wpackagist.org/ - this is a copy of the WP plugin directory specifically created so that a plugin from the directory can be conveniently added via composer (do not confuse it with packagist.org).

Note: All descriptions below assume that composer itself is already installed.

Installation from wpackagist.org

Create a file composer.json in the root folder of the project. This can be done manually or using the command:

$ composer init

Possible parameters of this file can be found in the documentation.

Suppose we created it with the following parameters:

{
  "name": "My Project",
  "description": "One more project.",
  "license": "proprietary",
  "authors": [
	{
	  "name": "Author Name",
	  "email": "[email protected]"
	}
  ],
}

Next. Since wpackagist.org is not the default repository (like packagist.org), it needs to be registered in the composer.json file so that composer knows there is another repository where packages can be searched for installation:

{
  ...
  "repositories": [
	{
	  "type": "composer",
	  "url": "https://wpackagist.org"
	},
  ]
}

Now in the require parameter, we need to add the name of the plugin we want to install. We also need to specify the extra.installer-paths parameter - the path to the folder with WP plugins where we want composer to install the plugins (packages).

For example, let's install the plugin redis-cache:

{
  "name": "My Project",
  "description": "One more project.",
  "license": "proprietary",
  "authors": [
	{
	  "name": "Author Name",
	  "email": "[email protected]"
	}
  ],
  "repositories": [
	{
	  "type": "composer",
	  "url": "https://wpackagist.org"
	}
  ],
  "require": {
	"wpackagist-plugin/redis-cache": "^2.4.4",
	"composer/installers": "*",
  },
  "extra": {
	"installer-paths": {
	  "path/to/wp-content/plugins/{$name}": [
		"type:wordpress-plugin"
	  ]
	}
  },
  "config": {
	"allow-plugins": {
	  "composer/installers": true
	}
  }
}

All plugins from the wpackagist.org repository have the type wordpress-plugin. In the installer-paths parameter, we specify that all plugins of this type should be installed in the specified folder, rather than in the default composer folder vendor.

Also, we are installing the package composer/installers, and in the config.allow-plugins parameter, we allow it to be loaded along with composer and extend its functionality.

The package composer/installers is the official composer package that allows specifying a directory other than vendor for installing packages. However, it allows changing the installation directory only for limited types of packages, for WordPress these are:

  • wordpress-plugin
  • wordpress-theme
  • wordpress-muplugin
  • wordpress-dropin

That's it! Now, to install the plugin, we need to run the command:

$ composer install

Plugin Version Issue from wpackagist.org

wpackagist.org copies the WP plugin repository (https://plugins.svn.wordpress.org/) and does not care about preserving previous versions. Therefore, the presence or absence of a specific version of a plugin falls on the shoulders of the developer. The developer must maintain what are called tags (SVN directory tags). That is, when publishing each version, the developer must ensure that the published version of the plugin is created (and remains in the future) in the tags directory.

To better understand what this means, let's look at an example. Let's take the plugin wp-sitemap-page. Suppose we specified a specific version 1.6 (this was the last version at the time of installing the plugin):

"require": {
  "wpackagist-plugin/wp-sitemap-page": "1.6"
}

Time passed and the plugin had a new version 1.7. Now, if we run composer install for an environment where there are no files of this plugin in the required folder (for example, when deploying to a dev or prod server we always reinstall all packages), version 1.7 will be installed, despite the fact that composer.json strictly states that we need version 1.6.

This happens because wpackagist.org simply copies the WP repository and if we look in the tags directory (plugin versions) https://plugins.svn.wordpress.org/wp-sitemap-page/tags/, we will not find the version 1.6 we need, which means it cannot be downloaded and therefore the latest dev version from the /trunk directory will be downloaded.

This can also be seen in the composer.lock file. The URL for downloading does not contain any version and points to the current version from the trunk directory:

Fortunately, according to my observations, there are fewer and fewer such plugins in the WP repository. Especially if the plugin is popular (although there are similar glitches there too).

Installation from packagist.org

Some plugin authors add their plugins to the default repository https://packagist.org/ and in this case, plugins can be installed from there.

Everything is done similarly here, with the only difference being that we do not need to specify an additional repository.

For example, the same plugin redis-cache can be installed as the package rhubarbgroup/redis-cache, in this case, we do not need to specify the "repositories" configuration. The composer.json will look like this:

{
  "name": "My Project",
  "description": "One more project.",
  "license": "proprietary",
  "authors": [
	{
	  "name": "Author Name",
	  "email": "[email protected]"
	}
  ],
  "require": {
	"rhubarbgroup/redis-cache": "^2.4.4",
	"composer/installers": "*",
  },
  "extra": {
	"installer-paths": {
	  "path/to/wp-content/plugins/{$name}": [
		"type:wordpress-plugin"
	  ]
	}
  },
  "config": {
	"allow-plugins": {
	  "composer/installers": true
	}
  }
}

The downside of this installation is that it is unclear that the package rhubarbgroup/redis-cache is a WP plugin, not a PHP package. However, it is free from another downside, which is described above (versioning works more reliably).