mirror of
https://ghproxy.net/https://github.com/wp-cli/extension-command.git
synced 2025-10-04 19:59:13 +08:00
Remove WP-CLI files unrelated to wp package *
This commit is contained in:
parent
d917e0c80e
commit
8ad684f90a
31 changed files with 0 additions and 4512 deletions
|
@ -1,23 +0,0 @@
|
|||
# This file is for unifying the coding style for different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
# WordPress Coding Standards
|
||||
# http://make.wordpress.org/core/handbook/coding-standards/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.{json,yml,feature}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[composer.json]
|
||||
indent_style = space
|
||||
indent_size = 4
|
15
.github/ISSUE_TEMPLATE
vendored
15
.github/ISSUE_TEMPLATE
vendored
|
@ -1,15 +0,0 @@
|
|||
<!--
|
||||
|
||||
Thanks for taking the time to help improve WP-CLI!
|
||||
|
||||
Found a bug or want to suggest an enhancement to an existing command? Before creating an issue, please review our best practices: http://wp-cli.org/docs/bug-reports/
|
||||
|
||||
But first, make sure you're running the most recent version of WP-CLI! The current version is the only officially supported version.
|
||||
|
||||
Need help with something? Github issues aren't for general support questions, but there are other venues you can try: http://wp-cli.org/#support
|
||||
|
||||
Want to suggest a feature? Check out the roadmap for how feature development happens: https://wp-cli.org/docs/roadmap/
|
||||
|
||||
You can safely delete this comment.
|
||||
|
||||
-->
|
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -1,10 +0,0 @@
|
|||
.DS_Store
|
||||
config.yml
|
||||
PHAR_BUILD_VERSION
|
||||
/cache
|
||||
/packages
|
||||
/vendor
|
||||
/*.phar
|
||||
/phpunit.xml.dist
|
||||
/codesniffer
|
||||
/PHP_Codesniffer-VariableAnalysis
|
|
@ -1,43 +0,0 @@
|
|||
Contributing
|
||||
============
|
||||
|
||||
Welcome and thanks!
|
||||
|
||||
We appreciate you taking the initiative to contribute to WP-CLI. It’s because of you, and the community around you, that WP-CLI is such a great project.
|
||||
|
||||
**Contributing isn’t limited to just code.** We encourage you to contribute in the way that best fits your abilities, by writing tutorials, giving a demo at your local meetup, helping other users with their support questions, or revising our documentation.
|
||||
|
||||
Please take a moment to read these guidelines at depth. Following the guidelines helps to communicate that you respect the time of the other contributors to the project. In turn, they’ll do their best to reciprocate that respect when working with you, across timezones and around the world.
|
||||
|
||||
### Reporting a bug
|
||||
|
||||
Think you’ve found a bug? We’d love for you to help us get it fixed.
|
||||
|
||||
Before you create a new issue, you should [search existing issues](https://github.com/wp-cli/wp-cli/issues?utf8=%E2%9C%93&q=label%3Abug%20) to see if there’s an existing resolution to it, or if it’s already been fixed in a newer version of WP-CLI. You should also check our [documentation on common issues and their fixes](https://wp-cli.org/docs/common-issues/).
|
||||
|
||||
Once you’ve done a bit of searching and discovered there isn’t an open or fixed issue for your bug, please [follow our guidelines for submitting a bug report](http://wp-cli.org/docs/bug-reports/) to make sure it gets addressed in a timely manner.
|
||||
|
||||
### Creating a pull request
|
||||
|
||||
Want to contribute a new feature? WP-CLI is a mature project, and already chock-full of useful functionality. Please first [open a new issue](https://github.com/wp-cli/wp-cli/issues/new) to discuss whether the feature is a good fit for WP-CLI core, or might be better suited as a [community package](https://wp-cli.org/package-index/).
|
||||
|
||||
New to the WP-CLI codebase? Check out [issues labeled 'good-first-issue'](https://github.com/wp-cli/wp-cli/labels/good-first-issue) for a place to start. These issues are specially earmarked for new contributors.
|
||||
|
||||
Once you've decided to commit the time to seeing your pull request through, please [follow our guidelines for creating a pull request](https://wp-cli.org/docs/pull-requests/) to make sure it's a pleasant experience.
|
||||
|
||||
### Improving our documentation
|
||||
|
||||
Is documentation your strength? Take a look at the currently open [documentation issues](https://github.com/wp-cli/wp-cli/issues?q=is%3Aopen+is%3Aissue+label%3Ascope%3Adocumentation) and see if you can tackle any of those.
|
||||
|
||||
If you believe you’ve found an issue with the documentation, you should [search existing issues](https://github.com/wp-cli/wp-cli/issues?utf8=%E2%9C%93&q=label%3Abug%20) to see if there’s an existing resolution to it, or if it’s already been fixed in a newer version of WP-CLI.
|
||||
|
||||
There are a couple different types of documentation currently part of WP-CLI:
|
||||
|
||||
* Documentation for individual WP-CLI commands (anything underneath [http://wp-cli.org/commands](http://wp-cli.org/commands)) is contained in the PHPDoc for each command. This means that to edit the documentation for a command, you will need to edit the file that actually provides the functionality for that command. The web documentation is generated from these files at the time of release, so you may not see your changes until the next release.
|
||||
* Individual documentation pages (anything under [http://wp-cli.org/docs/](http://wp-cli.org/docs/) can be edited by contributing to the [wp-cli.github.com repository on GitHub](https://github.com/wp-cli/wp-cli.github.com). You don't necessarily need to navigate the Github repo though; any page that is part of this repository will have an 'Edit' link in the top right of the page which will take you to the corresponding file on GitHub.
|
||||
|
||||
### Contributing in other ways
|
||||
|
||||
Feel free to [create an issue](https://github.com/wp-cli/wp-cli/issues/new) with your question, and we'll see if we can find an answer for it.
|
||||
|
||||
Alternatively, if you have a WordPress.org account, you may also consider joining the `#cli` channel on the [WordPress.org Slack organization](https://make.wordpress.org/chat/).
|
21
LICENSE
21
LICENSE
|
@ -1,21 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2011-2017 WP-CLI Development Group (https://github.com/wp-cli/wp-cli/contributors)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
193
README.md
193
README.md
|
@ -1,193 +0,0 @@
|
|||
WP-CLI
|
||||
======
|
||||
|
||||
[WP-CLI](https://wp-cli.org/) is a set of command-line tools for managing [WordPress](https://wordpress.org/) installations. You can update plugins, configure multisite installs and much more, without using a web browser.
|
||||
|
||||
For announcements, follow [@wpcli on Twitter](https://twitter.com/wpcli) or [sign up for email updates](https://make.wordpress.org/cli/subscribe/). [Check out the roadmap](https://wp-cli.org/docs/roadmap/) for an overview of what's planned for upcoming releases.
|
||||
|
||||
[](https://travis-ci.org/wp-cli/wp-cli) [](https://gemnasium.com/github.com/wp-cli/wp-cli) [](https://isitmaintained.com/project/wp-cli/wp-cli "Average time to resolve an issue") [](https://isitmaintained.com/project/wp-cli/wp-cli "Percentage of issues still open")
|
||||
|
||||
Quick links: [Using](#using) | [Installing](#installing) | [Support](#support) | [Extending](#extending) | [Contributing](#contributing) | [Credits](#credits)
|
||||
|
||||
## Using
|
||||
|
||||
WP-CLI's goal is to provide a command-line interface for any action you might want to perform in the WordPress admin. For instance, `wp plugin install --activate` ([doc](https://wp-cli.org/commands/plugin/install/)) lets you install and activate a WordPress plugin:
|
||||
|
||||
```bash
|
||||
$ wp plugin install rest-api --activate
|
||||
Installing WordPress REST API (Version 2) (2.0-beta13)
|
||||
Downloading install package from https://downloads.wordpress.org/plugin/rest-api.2.0-beta13.zip...
|
||||
Unpacking the package...
|
||||
Installing the plugin...
|
||||
Plugin installed successfully.
|
||||
Activating 'rest-api'...
|
||||
Success: Plugin 'rest-api' activated.
|
||||
```
|
||||
|
||||
WP-CLI also includes commands for many things you can't do in the WordPress admin. For example, `wp transient delete --all` ([doc](https://wp-cli.org/commands/transient/delete/)) lets you delete one or all transients:
|
||||
|
||||
```bash
|
||||
$ wp transient delete --all
|
||||
Success: 34 transients deleted from the database.
|
||||
```
|
||||
|
||||
For a more complete introduction to using WP-CLI, read the [Quick Start guide](https://wp-cli.org/docs/quick-start/). Or, catch up with [shell friends](https://wp-cli.org/docs/shell-friends/) to learn about helpful command line utilities.
|
||||
|
||||
Already feel comfortable with the basics? Jump into the [complete list of commands](https://wp-cli.org/commands/) for detailed information on managing themes and plugins, importing and exporting data, performing database search-replace operations and more.
|
||||
|
||||
## Installing
|
||||
|
||||
Downloading the Phar file is our recommended installation method. Should you need, see also our documentation on [alternative installation methods](https://wp-cli.org/docs/installing/).
|
||||
|
||||
Before installing WP-CLI, please make sure your environment meets the minimum requirements:
|
||||
|
||||
- UNIX-like environment (OS X, Linux, FreeBSD, Cygwin); limited support in Windows environment
|
||||
- PHP 5.3.29 or later
|
||||
- WordPress 3.7 or later
|
||||
|
||||
Once you've verified requirements, download the [wp-cli.phar](https://raw.github.com/wp-cli/builds/gh-pages/phar/wp-cli.phar) file using `wget` or `curl`:
|
||||
|
||||
```bash
|
||||
$ curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
|
||||
```
|
||||
|
||||
Next, check if it is working:
|
||||
|
||||
```bash
|
||||
$ php wp-cli.phar --info
|
||||
```
|
||||
|
||||
To use WP-CLI from the command line by typing `wp`, make the file executable and move it to somewhere in your PATH. For example:
|
||||
|
||||
```bash
|
||||
$ chmod +x wp-cli.phar
|
||||
$ sudo mv wp-cli.phar /usr/local/bin/wp
|
||||
```
|
||||
|
||||
If WP-CLI was installed successfully, you should see something like this when you run `wp --info`:
|
||||
|
||||
```bash
|
||||
$ wp --info
|
||||
PHP binary: /usr/bin/php5
|
||||
PHP version: 5.5.9-1ubuntu4.14
|
||||
php.ini used: /etc/php5/cli/php.ini
|
||||
WP-CLI root dir: /home/wp-cli/.wp-cli
|
||||
WP-CLI packages dir: /home/wp-cli/.wp-cli/packages/
|
||||
WP-CLI global config: /home/wp-cli/.wp-cli/config.yml
|
||||
WP-CLI project config:
|
||||
WP-CLI version: 1.1.0
|
||||
```
|
||||
|
||||
### Updating
|
||||
|
||||
You can update WP-CLI with `wp cli update` ([doc](https://wp-cli.org/commands/cli/update/)), or by repeating the installation steps.
|
||||
|
||||
If WP-CLI is owned by root or another system user, you'll need to run `sudo wp cli update`.
|
||||
|
||||
Want to live life on the edge? Run `wp cli update --nightly` to use the latest nightly build of WP-CLI. The nightly build is more or less stable enough for you to use in your development environment, and always includes the latest and greatest WP-CLI features.
|
||||
|
||||
### Tab completions
|
||||
|
||||
WP-CLI also comes with a tab completion script for Bash and ZSH. Just download [wp-completion.bash](https://raw.githubusercontent.com/wp-cli/wp-cli/master/utils/wp-completion.bash) and source it from `~/.bash_profile`:
|
||||
|
||||
```bash
|
||||
source /FULL/PATH/TO/wp-completion.bash
|
||||
```
|
||||
|
||||
Don't forget to run `source ~/.bash_profile` afterwards.
|
||||
|
||||
If using zsh for your shell, you may need to load and start `bashcompinit` before sourcing. Put the following in your `.zshrc`:
|
||||
|
||||
```bash
|
||||
autoload bashcompinit
|
||||
bashcompinit
|
||||
source /FULL/PATH/TO/wp-completion.bash
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
WP-CLI's maintainers and project contributors have limited availability to address general support questions. The [current version of WP-CLI](https://wp-cli.org/docs/roadmap/) is the only officially supported version.
|
||||
|
||||
When looking for support, please first look for an answer in one of the following resources:
|
||||
|
||||
- [Common issues and their fixes](https://wp-cli.org/docs/common-issues/)
|
||||
- [Documentation portal](https://wp-cli.org/docs/)
|
||||
- [Open or closed issues on Github](https://github.com/wp-cli/wp-cli/issues?utf8=%E2%9C%93&q=is%3Aissue)
|
||||
- [runcommand tips](https://runcommand.io/tips/)
|
||||
- [WordPress StackExchange forums](https://wordpress.stackexchange.com/questions/tagged/wp-cli)
|
||||
|
||||
You can also join the `#cli` channel on the [WordPress.org Slack organization](https://make.wordpress.org/chat/) to see if a community member might have an answer for you.
|
||||
|
||||
Github issues are meant for tracking enhancements and bugs of existing commands, not general support. Before submitting a bug report, please [review our best practices](https://wp-cli.org/docs/bug-reports/) to help ensure your issue is addressed in a timely manner.
|
||||
|
||||
Please do not ask support questions on Twitter. Twitter isn't an acceptable venue for support because: 1) it's hard to hold conversations in under 140 characters, and 2) Twitter isn't a place where someone with your same question can search for an answer in a prior conversation.
|
||||
|
||||
Remember, libre != gratis; the open source license grants you the freedom to use and modify, but not commitments of other people's time. Please be respectful, and set your expectations accordingly.
|
||||
|
||||
## Extending
|
||||
|
||||
A **command** is an atomic unit of WP-CLI functionality. `wp plugin install` ([doc](https://wp-cli.org/commands/plugin/install/)) is one command. `wp plugin activate` ([doc](https://wp-cli.org/commands/plugin/activate/)) is another.
|
||||
|
||||
WP-CLI supports registering any callable class, function, or closure as a command. It reads usage details from the callback's PHPdoc. `WP_CLI::add_command()` ([doc](https://wp-cli.org/docs/internal-api/wp-cli-add-command/)) is used for both internal and third-party command registration.
|
||||
|
||||
```php
|
||||
/**
|
||||
* Delete an option from the database.
|
||||
*
|
||||
* Returns an error if the option didn't exist.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <key>
|
||||
* : Key for the option.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* $ wp option delete my_option
|
||||
* Success: Deleted 'my_option' option.
|
||||
*/
|
||||
$delete_option_cmd = function( $args ) {
|
||||
list( $key ) = $args;
|
||||
|
||||
if ( ! delete_option( $key ) ) {
|
||||
WP_CLI::error( "Could not delete '$key' option. Does it exist?" );
|
||||
} else {
|
||||
WP_CLI::success( "Deleted '$key' option." );
|
||||
}
|
||||
};
|
||||
WP_CLI::add_command( 'option delete', $delete_option_cmd );
|
||||
```
|
||||
|
||||
WP-CLI comes with dozens of commands. It's easier than it looks to create a custom WP-CLI command. Read the [commands cookbook](https://wp-cli.org/docs/commands-cookbook/) to learn more. Browse the [internal API docs](https://wp-cli.org/docs/internal-api/) to discover a variety of helpful functions you can use in your custom WP-CLI command.
|
||||
|
||||
## Contributing
|
||||
|
||||
Welcome and thanks!
|
||||
|
||||
We appreciate you taking the initiative to contribute to WP-CLI. It’s because of you, and the community around you, that WP-CLI is such a great project.
|
||||
|
||||
**Contributing isn’t limited to just code.** We encourage you to contribute in the way that best fits your abilities, by writing tutorials, giving a demo at your local meetup, helping other users with their support questions, or revising our documentation.
|
||||
|
||||
Please take a moment to [read these guidelines at depth](https://wp-cli.org/docs/contributing/). Following them helps to communicate that you respect the time of the other contributors to the project. In turn, they’ll do their best to reciprocate that respect when working with you, across timezones and around the world.
|
||||
|
||||
## Leadership
|
||||
|
||||
WP-CLI is led by these individuals:
|
||||
|
||||
* [Daniel Bachhuber](https://github.com/danielbachhuber/) - current maintainer
|
||||
* [Cristi Burcă](https://github.com/scribu) - previous maintainer
|
||||
* [Andreas Creten](https://github.com/andreascreten) - founder
|
||||
|
||||
Read more about the project's [governance](https://wp-cli.org/docs/governance/) and view a [complete list of contributors](https://github.com/wp-cli/wp-cli/contributors).
|
||||
|
||||
## Credits
|
||||
|
||||
Besides the libraries defined in [composer.json](composer.json), we have used code or ideas from the following projects:
|
||||
|
||||
* [Drush](https://github.com/drush-ops/drush) for... a lot of things
|
||||
* [wpshell](https://code.trac.wordpress.org/browser/wpshell) for `wp shell`
|
||||
* [Regenerate Thumbnails](https://wordpress.org/plugins/regenerate-thumbnails/) for `wp media regenerate`
|
||||
* [Search-Replace-DB](https://github.com/interconnectit/Search-Replace-DB) for `wp search-replace`
|
||||
* [WordPress-CLI-Exporter](https://github.com/Automattic/WordPress-CLI-Exporter) for `wp export`
|
||||
* [WordPress-CLI-Importer](https://github.com/Automattic/WordPress-CLI-Importer) for `wp import`
|
||||
* [wordpress-plugin-tests](https://github.com/benbalter/wordpress-plugin-tests/) for `wp scaffold plugin-tests`
|
|
@ -1,51 +0,0 @@
|
|||
{
|
||||
"name": "wp-cli/wp-cli",
|
||||
"description": "A command line interface for WordPress",
|
||||
"keywords": [ "cli", "wordpress" ],
|
||||
"homepage": "http://wp-cli.org",
|
||||
"license": "MIT",
|
||||
"support": {
|
||||
"issues": "https://github.com/wp-cli/wp-cli/issues",
|
||||
"source": "https://github.com/wp-cli/wp-cli",
|
||||
"docs": "https://make.wordpress.org/cli/handbook/"
|
||||
},
|
||||
"bin": [
|
||||
"bin/wp.bat", "bin/wp"
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.29",
|
||||
"wp-cli/php-cli-tools": "~0.11.2",
|
||||
"mustache/mustache": "~2.4",
|
||||
"mustangostang/spyc": "~0.5",
|
||||
"composer/semver": "~1.0",
|
||||
"ramsey/array_column": "~1.1",
|
||||
"rmccue/requests" : "~1.6",
|
||||
"symfony/finder": "~2.7",
|
||||
"symfony/yaml": "~2.7",
|
||||
"symfony/filesystem": "~2.7",
|
||||
"symfony/config": "~2.7",
|
||||
"symfony/console": "~2.7",
|
||||
"symfony/debug": "~2.7",
|
||||
"symfony/dependency-injection": "~2.7",
|
||||
"symfony/event-dispatcher": "~2.7",
|
||||
"symfony/process": "~2.1",
|
||||
"symfony/translation": "~2.7",
|
||||
"composer/composer": "^1.2.0",
|
||||
"wp-cli/cron-command": "^1.0",
|
||||
"wp-cli/import-command": "^1.0",
|
||||
"wp-cli/db-command": "^1.0",
|
||||
"wp-cli/media-command": "^1.0",
|
||||
"wp-cli/export-command": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "3.7.*",
|
||||
"behat/behat": "2.5.*",
|
||||
"roave/security-advisories": "dev-master"
|
||||
},
|
||||
"suggest": {
|
||||
"psy/psysh": "Enhanced `wp shell` functionality"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "WP_CLI": "php" }
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
Feature: Activate WordPress plugins
|
||||
|
||||
Background:
|
||||
Given a WP install
|
||||
|
||||
Scenario: Activate a plugin that's already installed
|
||||
When I run `wp plugin activate akismet`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Plugin 'akismet' activated.
|
||||
Success: Activated 1 of 1 plugins.
|
||||
"""
|
||||
And the return code should be 0
|
||||
|
||||
Scenario: Attempt to activate a plugin that's not installed
|
||||
When I try `wp plugin activate edit-flow`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: The 'edit-flow' plugin could not be found.
|
||||
Error: No plugins activated.
|
||||
"""
|
||||
And the return code should be 1
|
||||
|
||||
When I try `wp plugin activate akismet hello edit-flow`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: The 'edit-flow' plugin could not be found.
|
||||
Error: Only activated 2 of 3 plugins.
|
||||
"""
|
||||
And STDOUT should be:
|
||||
"""
|
||||
Plugin 'akismet' activated.
|
||||
Plugin 'hello' activated.
|
||||
"""
|
||||
And the return code should be 1
|
|
@ -1,36 +0,0 @@
|
|||
Feature: Deactivate WordPress plugins
|
||||
|
||||
Background:
|
||||
Given a WP install
|
||||
And I run `wp plugin activate akismet hello`
|
||||
|
||||
Scenario: Deactivate a plugin that's already activated
|
||||
When I run `wp plugin deactivate akismet`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Plugin 'akismet' deactivated.
|
||||
Success: Deactivated 1 of 1 plugins.
|
||||
"""
|
||||
And the return code should be 0
|
||||
|
||||
Scenario: Attempt to deactivate a plugin that's not installed
|
||||
When I try `wp plugin deactivate edit-flow`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: The 'edit-flow' plugin could not be found.
|
||||
Error: No plugins deactivated.
|
||||
"""
|
||||
And the return code should be 1
|
||||
|
||||
When I try `wp plugin deactivate akismet hello edit-flow`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: The 'edit-flow' plugin could not be found.
|
||||
Error: Only deactivated 2 of 3 plugins.
|
||||
"""
|
||||
And STDOUT should be:
|
||||
"""
|
||||
Plugin 'akismet' deactivated.
|
||||
Plugin 'hello' deactivated.
|
||||
"""
|
||||
And the return code should be 1
|
|
@ -1,25 +0,0 @@
|
|||
Feature: Delete WordPress plugins
|
||||
|
||||
Background:
|
||||
Given a WP install
|
||||
|
||||
Scenario: Delete an installed plugin
|
||||
When I run `wp plugin delete akismet`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Deleted 'akismet' plugin.
|
||||
Success: Deleted 1 of 1 plugins.
|
||||
"""
|
||||
And the return code should be 0
|
||||
|
||||
Scenario: Attempting to delete a plugin that doesn't exist
|
||||
When I run `wp plugin delete edit-flow`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Success: Plugin already deleted.
|
||||
"""
|
||||
And STDERR should be:
|
||||
"""
|
||||
Warning: The 'edit-flow' plugin could not be found.
|
||||
"""
|
||||
And the return code should be 0
|
|
@ -1,143 +0,0 @@
|
|||
Feature: Install WordPress plugins
|
||||
|
||||
Scenario: Branch names should be removed from Github projects
|
||||
Given a WP install
|
||||
|
||||
When I run `wp plugin install https://github.com/runcommand/one-time-login/archive/master.zip --activate`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Downloading install package from https://github.com/runcommand/one-time-login/archive/master.zip
|
||||
"""
|
||||
And STDOUT should contain:
|
||||
"""
|
||||
Renamed Github-based project from 'one-time-login-master' to 'one-time-login'.
|
||||
"""
|
||||
And STDOUT should contain:
|
||||
"""
|
||||
Plugin installed successfully.
|
||||
"""
|
||||
And STDERR should be empty
|
||||
And the wp-content/plugins/one-time-login directory should exist
|
||||
And the wp-content/plugins/one-time-login-master directory should not exist
|
||||
|
||||
When I try `wp plugin install https://github.com/runcommand/one-time-login/archive/master.zip`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
Warning: Destination folder already exists
|
||||
"""
|
||||
And the wp-content/plugins/one-time-login directory should exist
|
||||
And the wp-content/plugins/one-time-login-master directory should not exist
|
||||
|
||||
When I run `wp plugin install https://github.com/runcommand/one-time-login/archive/master.zip --force`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Plugin updated successfully.
|
||||
"""
|
||||
And the wp-content/plugins/one-time-login directory should exist
|
||||
And the wp-content/plugins/one-time-login-master directory should not exist
|
||||
|
||||
Scenario: Don't attempt to rename ZIPs uploaded to GitHub's releases page
|
||||
Given a WP install
|
||||
|
||||
When I run `wp plugin install https://github.com/danielbachhuber/one-time-login/releases/download/v0.1.2/one-time-login.0.1.2.zip`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Plugin installed successfully.
|
||||
"""
|
||||
And STDOUT should not contain:
|
||||
"""
|
||||
Renamed Github-based project from
|
||||
"""
|
||||
And STDERR should be empty
|
||||
And the wp-content/plugins/one-time-login directory should exist
|
||||
|
||||
Scenario: Don't attempt to rename ZIPs coming from a GitHub raw source
|
||||
Given a WP install
|
||||
|
||||
When I run `wp plugin install https://github.com/Miller-Media/modern-wordpress/raw/master/builds/modern-framework-stable.zip`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Plugin installed successfully.
|
||||
"""
|
||||
And STDOUT should not contain:
|
||||
"""
|
||||
Renamed Github-based project from
|
||||
"""
|
||||
And STDERR should be empty
|
||||
And the wp-content/plugins/modern-framework directory should exist
|
||||
|
||||
Scenario: Installing respects WP_PROXY_HOST and WP_PROXY_PORT
|
||||
Given a WP install
|
||||
And a invalid-proxy-details.php file:
|
||||
"""
|
||||
<?php
|
||||
define( 'WP_PROXY_HOST', 'https://wp-cli.org' );
|
||||
define( 'WP_PROXY_PORT', '443' );
|
||||
"""
|
||||
|
||||
When I try `wp --require=invalid-proxy-details.php plugin install edit-flow`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
Warning: edit-flow: An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration.
|
||||
"""
|
||||
And STDOUT should be empty
|
||||
|
||||
When I run `wp plugin install edit-flow`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Plugin installed successfully.
|
||||
"""
|
||||
And STDERR should be empty
|
||||
|
||||
Scenario: Return code is 1 when one or more plugin installations fail
|
||||
Given a WP install
|
||||
|
||||
When I try `wp plugin install user-switching user-switching-not-a-plugin`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: Couldn't find 'user-switching-not-a-plugin' in the WordPress.org plugin directory.
|
||||
Error: Only installed 1 of 2 plugins.
|
||||
"""
|
||||
And STDOUT should contain:
|
||||
"""
|
||||
Installing User Switching
|
||||
"""
|
||||
And STDOUT should contain:
|
||||
"""
|
||||
Plugin installed successfully.
|
||||
"""
|
||||
And the return code should be 1
|
||||
|
||||
When I run `wp plugin install user-switching`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Success: Plugin already installed.
|
||||
"""
|
||||
And STDERR should be:
|
||||
"""
|
||||
Warning: user-switching: Plugin already installed.
|
||||
"""
|
||||
And the return code should be 0
|
||||
|
||||
When I try `wp plugin install user-switching-not-a-plugin`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: Couldn't find 'user-switching-not-a-plugin' in the WordPress.org plugin directory.
|
||||
Error: No plugins installed.
|
||||
"""
|
||||
And the return code should be 1
|
||||
|
||||
Scenario: Paths aren't backslashed when destination folder already exists
|
||||
Given a WP install
|
||||
|
||||
When I run `pwd`
|
||||
Then save STDOUT as {WORKING_DIR}
|
||||
|
||||
When I run `rm wp-content/plugins/akismet/akismet.php`
|
||||
Then the return code should be 0
|
||||
|
||||
When I try `wp plugin install akismet`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
Warning: Destination folder already exists. "{WORKING_DIR}/wp-content/plugins/akismet/"
|
||||
"""
|
|
@ -1,14 +0,0 @@
|
|||
Feature: Search WordPress.org plugins
|
||||
|
||||
Scenario: Search for plugins with active_installs field
|
||||
Given a WP install
|
||||
|
||||
When I run `wp plugin search foo --fields=name,slug,active_installs --format=csv`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Success: Showing
|
||||
"""
|
||||
And STDOUT should contain:
|
||||
"""
|
||||
name,slug,active_installs
|
||||
"""
|
|
@ -1,42 +0,0 @@
|
|||
Feature: Toggle the activation status of a plugin
|
||||
|
||||
Background:
|
||||
Given a WP install
|
||||
|
||||
Scenario: Toggle the status of a plugin
|
||||
When I run `wp plugin toggle akismet`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Plugin 'akismet' activated.
|
||||
Success: Toggled 1 of 1 plugins.
|
||||
"""
|
||||
|
||||
When I run `wp plugin toggle akismet`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Plugin 'akismet' deactivated.
|
||||
Success: Toggled 1 of 1 plugins.
|
||||
"""
|
||||
|
||||
Scenario: Toggling the status of a plugin that doesn't exist
|
||||
When I try `wp plugin toggle akismet edit-flow`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: The 'edit-flow' plugin could not be found.
|
||||
Error: Only toggled 1 of 2 plugins.
|
||||
"""
|
||||
And STDOUT should be:
|
||||
"""
|
||||
Plugin 'akismet' activated.
|
||||
"""
|
||||
And the return code should be 1
|
||||
|
||||
When I try `wp plugin toggle edit-flow co-authors-plus`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: The 'edit-flow' plugin could not be found.
|
||||
Warning: The 'co-authors-plus' plugin could not be found.
|
||||
Error: No plugins toggled.
|
||||
"""
|
||||
And STDOUT should be empty
|
||||
And the return code should be 1
|
|
@ -1,37 +0,0 @@
|
|||
Feature: Uninstall a WordPress plugin
|
||||
|
||||
Background:
|
||||
Given a WP install
|
||||
|
||||
Scenario: Uninstall an installed plugin
|
||||
When I run `wp plugin uninstall akismet`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Uninstalled and deleted 'akismet' plugin.
|
||||
Success: Uninstalled 1 of 1 plugins.
|
||||
"""
|
||||
And the return code should be 0
|
||||
|
||||
Scenario: Attempting to uninstall a plugin that's activated
|
||||
When I run `wp plugin activate akismet`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I try `wp plugin uninstall akismet`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: The 'akismet' plugin is active.
|
||||
Error: No plugins uninstalled.
|
||||
"""
|
||||
And the return code should be 1
|
||||
|
||||
Scenario: Attempting to uninstall a plugin that doesn't exist
|
||||
When I run `wp plugin uninstall edit-flow`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Success: Plugin already uninstalled.
|
||||
"""
|
||||
And STDERR should be:
|
||||
"""
|
||||
Warning: The 'edit-flow' plugin could not be found.
|
||||
"""
|
||||
And the return code should be 0
|
|
@ -1,35 +0,0 @@
|
|||
Feature: Update WordPress plugins
|
||||
|
||||
Scenario: Updating plugin with invalid version shouldn't remove the old version
|
||||
Given a WP install
|
||||
|
||||
When I run `wp plugin install akismet --version=2.5.6 --force`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp plugin list --name=akismet --field=update_version`
|
||||
Then STDOUT should not be empty
|
||||
And save STDOUT as {UPDATE_VERSION}
|
||||
|
||||
When I run `wp plugin list`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status | update | version |
|
||||
| akismet | inactive | available | 2.5.6 |
|
||||
|
||||
When I try `wp plugin update akismet --version=2.9.0`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Error: Can't find the requested plugin's version 2.9.0 in the WordPress.org plugin repository (HTTP code 404).
|
||||
"""
|
||||
|
||||
When I run `wp plugin list`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status | update | version |
|
||||
| akismet | inactive | available | 2.5.6 |
|
||||
|
||||
When I run `wp plugin update akismet`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp plugin list`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status | update | version |
|
||||
| akismet | inactive | none | {UPDATE_VERSION} |
|
|
@ -1,476 +0,0 @@
|
|||
Feature: Manage WordPress plugins
|
||||
|
||||
Scenario: Create, activate and check plugin status
|
||||
Given a WP install
|
||||
And I run `wp plugin path`
|
||||
And save STDOUT as {PLUGIN_DIR}
|
||||
|
||||
When I run `wp plugin scaffold --skip-tests plugin1`
|
||||
Then STDOUT should not be empty
|
||||
And the {PLUGIN_DIR}/plugin1/plugin1.php file should exist
|
||||
And the {PLUGIN_DIR}/zombieland/phpunit.xml.dist file should not exist
|
||||
|
||||
When I run `wp plugin path plugin1`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
{PLUGIN_DIR}/plugin1/plugin1.php
|
||||
"""
|
||||
|
||||
When I run `wp plugin path plugin1 --dir`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
{PLUGIN_DIR}/plugin1
|
||||
"""
|
||||
|
||||
When I run `wp plugin scaffold Zombieland`
|
||||
Then STDOUT should not be empty
|
||||
And the {PLUGIN_DIR}/Zombieland/Zombieland.php file should exist
|
||||
And the {PLUGIN_DIR}/Zombieland/phpunit.xml.dist file should exist
|
||||
|
||||
# Ensure case sensitivity
|
||||
When I try `wp plugin status zombieLand`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
The 'zombieLand' plugin could not be found.
|
||||
"""
|
||||
|
||||
# Check that the inner-plugin is not picked up
|
||||
When I run `mv {PLUGIN_DIR}/plugin1 {PLUGIN_DIR}/Zombieland/`
|
||||
And I run `wp plugin status Zombieland`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Plugin Zombieland details:
|
||||
Name: Zombieland
|
||||
Status: Inactive
|
||||
Version: 0.1.0
|
||||
Author: YOUR NAME HERE
|
||||
Description: PLUGIN DESCRIPTION HERE
|
||||
"""
|
||||
|
||||
When I run `wp plugin activate Zombieland`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp plugin status Zombieland`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Status: Active
|
||||
"""
|
||||
|
||||
When I run `wp plugin status`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp plugin list`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status | update | version |
|
||||
| Zombieland | active | none | 0.1.0 |
|
||||
|
||||
When I try `wp plugin uninstall Zombieland`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
The 'Zombieland' plugin is active.
|
||||
"""
|
||||
|
||||
When I run `wp plugin deactivate Zombieland`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp option get recently_activated`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Zombieland/Zombieland.php
|
||||
"""
|
||||
|
||||
When I run `wp plugin uninstall Zombieland`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Uninstalled and deleted 'Zombieland' plugin.
|
||||
Success: Uninstalled 1 of 1 plugins.
|
||||
"""
|
||||
And the {PLUGIN_DIR}/zombieland file should not exist
|
||||
|
||||
When I try the previous command again
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
The 'Zombieland' plugin could not be found.
|
||||
"""
|
||||
|
||||
Scenario: Install a plugin, activate, then force install an older version of the plugin
|
||||
Given a WP install
|
||||
|
||||
When I run `wp plugin install akismet --version=2.5.7 --force`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp plugin list --name=akismet --field=update_version`
|
||||
Then STDOUT should not be empty
|
||||
And save STDOUT as {UPDATE_VERSION}
|
||||
|
||||
When I run `wp plugin list --fields=name,status,update,version,update_version`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status | update | version | update_version |
|
||||
| akismet | inactive | available | 2.5.7 | {UPDATE_VERSION} |
|
||||
|
||||
When I run `wp plugin activate akismet`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp plugin install akismet --version=2.5.6 --force`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp plugin list`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status | update | version |
|
||||
| akismet | active | available | 2.5.6 |
|
||||
|
||||
When I try `wp plugin update`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Error: Please specify one or more plugins, or use --all.
|
||||
"""
|
||||
|
||||
When I run `wp plugin update --all --format=summary | grep 'updated successfully from'`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Akismet updated successfully from version 2.5.6 to version
|
||||
"""
|
||||
|
||||
When I try `wp plugin update xxx yyy`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
Warning: The 'xxx' plugin could not be found.
|
||||
"""
|
||||
And STDERR should contain:
|
||||
"""
|
||||
Warning: The 'yyy' plugin could not be found.
|
||||
"""
|
||||
And STDERR should contain:
|
||||
"""
|
||||
Error: No plugins updated.
|
||||
"""
|
||||
|
||||
When I run `wp plugin install akismet --version=2.5.6 --force`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I try `wp plugin update akismet hello xxx`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
Warning: The 'xxx' plugin could not be found.
|
||||
"""
|
||||
And STDERR should contain:
|
||||
"""
|
||||
Error: Only updated 1 of 3 plugins.
|
||||
"""
|
||||
|
||||
Scenario: Activate a network-only plugin on single site
|
||||
Given a WP install
|
||||
And a wp-content/plugins/network-only.php file:
|
||||
"""
|
||||
// Plugin Name: Example Plugin
|
||||
// Network: true
|
||||
"""
|
||||
|
||||
When I run `wp plugin activate network-only`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Plugin 'network-only' activated.
|
||||
Success: Activated 1 of 1 plugins.
|
||||
"""
|
||||
|
||||
When I run `wp plugin status network-only`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Status: Active
|
||||
"""
|
||||
|
||||
Scenario: Activate a network-only plugin on multisite
|
||||
Given a WP multisite install
|
||||
And a wp-content/plugins/network-only.php file:
|
||||
"""
|
||||
// Plugin Name: Example Plugin
|
||||
// Network: true
|
||||
"""
|
||||
|
||||
When I run `wp plugin activate network-only`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Plugin 'network-only' network activated.
|
||||
Success: Activated 1 of 1 plugins.
|
||||
"""
|
||||
|
||||
When I run `wp plugin status network-only`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Status: Network Active
|
||||
"""
|
||||
|
||||
Scenario: Network activate a plugin
|
||||
Given a WP multisite install
|
||||
|
||||
When I run `wp plugin activate akismet`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Plugin 'akismet' activated.
|
||||
Success: Activated 1 of 1 plugins.
|
||||
"""
|
||||
|
||||
When I run `wp plugin list --fields=name,status`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status |
|
||||
| akismet | active |
|
||||
|
||||
When I run `wp plugin activate akismet`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
Warning: Plugin 'akismet' is already active.
|
||||
"""
|
||||
And STDOUT should be:
|
||||
"""
|
||||
Success: Plugin already activated.
|
||||
"""
|
||||
|
||||
When I run `wp plugin activate akismet --network`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Plugin 'akismet' network activated.
|
||||
Success: Network activated 1 of 1 plugins.
|
||||
"""
|
||||
|
||||
When I run `wp plugin activate akismet --network`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: Plugin 'akismet' is already network active.
|
||||
"""
|
||||
And STDOUT should be:
|
||||
"""
|
||||
Success: Plugin already network activated.
|
||||
"""
|
||||
|
||||
When I try `wp plugin deactivate akismet`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: Plugin 'akismet' is network active and must be deactivated with --network flag.
|
||||
Error: No plugins deactivated.
|
||||
"""
|
||||
And the return code should be 1
|
||||
|
||||
When I run `wp plugin deactivate akismet --network`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Plugin 'akismet' network deactivated.
|
||||
Success: Network deactivated 1 of 1 plugins.
|
||||
"""
|
||||
And the return code should be 0
|
||||
|
||||
When I run `wp plugin deactivate akismet`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: Plugin 'akismet' isn't active.
|
||||
"""
|
||||
And STDOUT should be:
|
||||
"""
|
||||
Success: Plugin already deactivated.
|
||||
"""
|
||||
And the return code should be 0
|
||||
|
||||
Scenario: List plugins
|
||||
Given a WP install
|
||||
|
||||
When I run `wp plugin activate akismet hello`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp plugin list --status=inactive --field=name`
|
||||
Then STDOUT should be empty
|
||||
|
||||
When I run `wp plugin list --status=active --fields=name,status`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status |
|
||||
| akismet | active |
|
||||
|
||||
Scenario: Install a plugin when directory doesn't yet exist
|
||||
Given a WP install
|
||||
|
||||
When I run `rm -rf wp-content/plugins`
|
||||
And I run `if test -d wp-content/plugins; then echo "fail"; fi`
|
||||
Then STDOUT should be empty
|
||||
|
||||
When I run `wp plugin install akismet --activate`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp plugin list --status=active --fields=name,status`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status |
|
||||
| akismet | active |
|
||||
|
||||
Scenario: Plugin name with HTML entities
|
||||
Given a WP install
|
||||
|
||||
When I run `wp plugin install debug-bar-list-dependencies`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Installing Debug Bar List Script & Style Dependencies
|
||||
"""
|
||||
|
||||
Scenario: Enable and disable all plugins
|
||||
Given a WP install
|
||||
|
||||
When I run `wp plugin activate --all`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Plugin 'akismet' activated.
|
||||
Plugin 'hello' activated.
|
||||
Success: Activated 2 of 2 plugins.
|
||||
"""
|
||||
|
||||
When I run `wp plugin activate --all`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Success: Plugins already activated.
|
||||
"""
|
||||
|
||||
When I run `wp plugin list --field=status`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
active
|
||||
active
|
||||
must-use
|
||||
"""
|
||||
|
||||
When I run `wp plugin deactivate --all`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Plugin 'akismet' deactivated.
|
||||
Plugin 'hello' deactivated.
|
||||
Success: Deactivated 2 of 2 plugins.
|
||||
"""
|
||||
|
||||
When I run `wp plugin deactivate --all`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Success: Plugins already deactivated.
|
||||
"""
|
||||
|
||||
When I run `wp plugin list --field=status`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
inactive
|
||||
inactive
|
||||
must-use
|
||||
"""
|
||||
|
||||
Scenario: Deactivate and uninstall a plugin, part one
|
||||
Given a WP install
|
||||
And these installed and active plugins:
|
||||
"""
|
||||
akismet
|
||||
"""
|
||||
|
||||
When I run `wp plugin deactivate akismet --uninstall`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Plugin 'akismet' deactivated.
|
||||
Uninstalling 'akismet'...
|
||||
Uninstalled and deleted 'akismet' plugin.
|
||||
Success: Deactivated 1 of 1 plugins.
|
||||
"""
|
||||
|
||||
When I try `wp plugin get akismet`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Error: The 'akismet' plugin could not be found.
|
||||
"""
|
||||
|
||||
Scenario: Deactivate and uninstall a plugin, part two
|
||||
Given a WP install
|
||||
And these installed and active plugins:
|
||||
"""
|
||||
akismet
|
||||
"""
|
||||
|
||||
When I run `wp plugin uninstall akismet --deactivate`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Deactivating 'akismet'...
|
||||
Plugin 'akismet' deactivated.
|
||||
Uninstalled and deleted 'akismet' plugin.
|
||||
Success: Uninstalled 1 of 1 plugins.
|
||||
"""
|
||||
|
||||
When I try `wp plugin get akismet`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Error: The 'akismet' plugin could not be found.
|
||||
"""
|
||||
|
||||
|
||||
Scenario: Uninstall a plugin without deleting
|
||||
Given a WP install
|
||||
|
||||
When I run `wp plugin install akismet --version=2.5.7 --force`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp plugin uninstall akismet --skip-delete`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Ran uninstall procedure for 'akismet' plugin without deleting.
|
||||
Success: Uninstalled 1 of 1 plugins.
|
||||
"""
|
||||
|
||||
Scenario: Two plugins, one directory
|
||||
Given a WP install
|
||||
And a wp-content/plugins/handbook/handbook.php file:
|
||||
"""
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: Handbook
|
||||
* Description: Features for a handbook, complete with glossary and table of contents
|
||||
* Author: Nacin
|
||||
*/
|
||||
"""
|
||||
And a wp-content/plugins/handbook/functionality-for-pages.php file:
|
||||
"""
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: Handbook Functionality for Pages
|
||||
* Description: Adds handbook-like table of contents to all Pages for a site. Covers Table of Contents and the "watch this page" widget
|
||||
* Author: Nacin
|
||||
*/
|
||||
"""
|
||||
|
||||
When I run `wp plugin list --fields=name,status`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status |
|
||||
| handbook/handbook | inactive |
|
||||
| handbook/functionality-for-pages | inactive |
|
||||
|
||||
When I run `wp plugin activate handbook/functionality-for-pages`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp plugin list --fields=name,status`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status |
|
||||
| handbook/handbook | inactive |
|
||||
| handbook/functionality-for-pages | active |
|
||||
|
||||
Scenario: Install a plugin, then update to a specific version of that plugin
|
||||
Given a WP install
|
||||
|
||||
When I run `wp plugin install akismet --version=2.5.7 --force`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp plugin update akismet --version=2.6.0`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp plugin list --fields=name,version`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | version |
|
||||
| akismet | 2.6.0 |
|
||||
|
||||
Scenario: Ignore empty slugs
|
||||
Given a WP install
|
||||
|
||||
When I run `wp plugin install ''`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
Warning: Ignoring ambigious empty slug value.
|
||||
"""
|
||||
And STDOUT should not contain:
|
||||
"""
|
||||
Plugin installed successfully
|
||||
"""
|
|
@ -1,29 +0,0 @@
|
|||
Feature: Delete WordPress themes
|
||||
|
||||
Background:
|
||||
Given a WP install
|
||||
And I run `wp theme install p2`
|
||||
|
||||
Scenario: Delete an installed theme
|
||||
When I run `wp theme delete p2`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Deleted 'p2' theme.
|
||||
Success: Deleted 1 of 1 themes.
|
||||
"""
|
||||
And the return code should be 0
|
||||
|
||||
Scenario: Attempting to delete a theme that doesn't exist
|
||||
When I run `wp theme delete p2`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run the previous command again
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Success: Theme already deleted.
|
||||
"""
|
||||
And STDERR should be:
|
||||
"""
|
||||
Warning: The 'p2' theme could not be found.
|
||||
"""
|
||||
And the return code should be 0
|
|
@ -1,73 +0,0 @@
|
|||
Feature: Install WordPress themes
|
||||
|
||||
Scenario: Return code is 1 when one or more theme installations fail
|
||||
Given a WP install
|
||||
|
||||
When I try `wp theme install p2 p2-not-a-theme`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: Couldn't find 'p2-not-a-theme' in the WordPress.org theme directory.
|
||||
Error: Only installed 1 of 2 themes.
|
||||
"""
|
||||
And STDOUT should contain:
|
||||
"""
|
||||
Installing P2
|
||||
"""
|
||||
And STDOUT should contain:
|
||||
"""
|
||||
Theme installed successfully.
|
||||
"""
|
||||
And the return code should be 1
|
||||
|
||||
When I run `wp theme install p2`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Success: Theme already installed.
|
||||
"""
|
||||
And STDERR should be:
|
||||
"""
|
||||
Warning: p2: Theme already installed.
|
||||
"""
|
||||
And the return code should be 0
|
||||
|
||||
When I try `wp theme install p2-not-a-theme`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: Couldn't find 'p2-not-a-theme' in the WordPress.org theme directory.
|
||||
Error: No themes installed.
|
||||
"""
|
||||
And the return code should be 1
|
||||
|
||||
Scenario: Ensure automatic parent theme installation uses http cacher
|
||||
Given a WP install
|
||||
And an empty cache
|
||||
|
||||
When I run `wp theme install stargazer`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Success: Installed 1 of 1 themes.
|
||||
"""
|
||||
And STDOUT should not contain:
|
||||
"""
|
||||
Using cached file
|
||||
"""
|
||||
|
||||
When I run `wp theme uninstall stargazer`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Success: Deleted 1 of 1 themes.
|
||||
"""
|
||||
|
||||
When I run `wp theme install buntu`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Success: Installed 1 of 1 themes.
|
||||
"""
|
||||
And STDOUT should contain:
|
||||
"""
|
||||
This theme requires a parent theme.
|
||||
"""
|
||||
And STDOUT should contain:
|
||||
"""
|
||||
Using cached file
|
||||
"""
|
|
@ -1,69 +0,0 @@
|
|||
Feature: Manage WordPress theme mods
|
||||
|
||||
Scenario: Getting theme mods
|
||||
Given a WP install
|
||||
|
||||
When I run `wp theme mod get --all`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| key | value |
|
||||
|
||||
When I try `wp theme mod get`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
You must specify at least one mod or use --all.
|
||||
"""
|
||||
|
||||
When I run `wp theme mod set background_color 123456`
|
||||
And I run `wp theme mod get --all`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| key | value |
|
||||
| background_color | 123456 |
|
||||
|
||||
When I run `wp theme mod get background_color --field=value`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
123456
|
||||
"""
|
||||
|
||||
When I run `wp theme mod set background_color 123456`
|
||||
And I run `wp theme mod get background_color header_textcolor`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| key | value |
|
||||
| background_color | 123456 |
|
||||
| header_textcolor | |
|
||||
|
||||
Scenario: Setting theme mods
|
||||
Given a WP install
|
||||
|
||||
When I run `wp theme mod set background_color 123456`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Success: Theme mod background_color set to 123456.
|
||||
"""
|
||||
|
||||
Scenario: Removing theme mods
|
||||
Given a WP install
|
||||
|
||||
When I run `wp theme mod remove --all`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Success: Theme mods removed.
|
||||
"""
|
||||
|
||||
When I try `wp theme mod remove`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
You must specify at least one mod or use --all.
|
||||
"""
|
||||
|
||||
When I run `wp theme mod remove background_color`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Success: 1 mod removed.
|
||||
"""
|
||||
|
||||
When I run `wp theme mod remove background_color header_textcolor`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Success: 2 mods removed.
|
||||
"""
|
|
@ -1,372 +0,0 @@
|
|||
Feature: Manage WordPress themes
|
||||
|
||||
Scenario: Installing and deleting theme
|
||||
Given a WP install
|
||||
|
||||
When I run `wp theme install p2`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp theme status p2`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Theme p2 details:
|
||||
Name: P2
|
||||
"""
|
||||
|
||||
When I run `wp theme path p2`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
/themes/p2/style.css
|
||||
"""
|
||||
|
||||
When I run `wp option get stylesheet`
|
||||
Then save STDOUT as {PREVIOUS_THEME}
|
||||
|
||||
When I run `wp theme activate p2`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Success: Switched to 'P2' theme.
|
||||
"""
|
||||
|
||||
When I try `wp theme delete p2`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: Can't delete the currently active theme: p2
|
||||
Error: No themes deleted.
|
||||
"""
|
||||
And STDOUT should be empty
|
||||
|
||||
When I run `wp theme activate {PREVIOUS_THEME}`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp theme delete p2`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I try the previous command again
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
The 'p2' theme could not be found.
|
||||
"""
|
||||
|
||||
When I run `wp theme list`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
Scenario: Checking theme status without theme parameter
|
||||
Given a WP install
|
||||
|
||||
When I run `wp theme install classic --activate`
|
||||
And I run `wp theme list --field=name --status=inactive | xargs wp theme delete`
|
||||
And I run `wp theme status`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
1 installed theme:
|
||||
A classic 1.6
|
||||
|
||||
Legend: A = Active
|
||||
"""
|
||||
|
||||
Scenario: Install a theme, activate, then force install an older version of the theme
|
||||
Given a WP install
|
||||
|
||||
When I run `wp theme install p2 --version=1.4.2`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp theme list`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status | update | version |
|
||||
| p2 | inactive | available | 1.4.2 |
|
||||
|
||||
When I run `wp theme activate p2`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp theme install p2 --version=1.4.1 --force`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp theme list`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status | update | version |
|
||||
| p2 | active | available | 1.4.1 |
|
||||
|
||||
When I try `wp theme update`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Error: Please specify one or more themes, or use --all.
|
||||
"""
|
||||
|
||||
When I run `wp theme update --all --format=summary | grep 'updated successfully from'`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
P2 updated successfully from version 1.4.1 to version
|
||||
"""
|
||||
|
||||
Scenario: Get the path of an installed theme
|
||||
Given a WP install
|
||||
|
||||
When I run `wp theme install p2`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp theme path p2 --dir`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
wp-content/themes/p2
|
||||
"""
|
||||
|
||||
Scenario: Activate an already active theme
|
||||
Given a WP install
|
||||
|
||||
When I run `wp theme install p2`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp theme activate p2`
|
||||
Then STDOUT should be:
|
||||
"""
|
||||
Success: Switched to 'P2' theme.
|
||||
"""
|
||||
|
||||
When I try `wp theme activate p2`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Warning: The 'P2' theme is already active.
|
||||
"""
|
||||
|
||||
Scenario: Install a theme when the theme directory doesn't yet exist
|
||||
Given a WP install
|
||||
|
||||
When I run `rm -rf wp-content/themes`
|
||||
And I run `if test -d wp-content/themes; then echo "fail"; fi`
|
||||
Then STDOUT should be empty
|
||||
|
||||
When I run `wp theme install p2 --activate`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp theme list --fields=name,status`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status |
|
||||
| p2 | active |
|
||||
|
||||
Scenario: Attempt to activate or fetch a broken theme
|
||||
Given a WP install
|
||||
|
||||
When I run `mkdir -pv wp-content/themes/myth`
|
||||
Then the wp-content/themes/myth directory should exist
|
||||
|
||||
When I try `wp theme activate myth`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
Error: Stylesheet is missing.
|
||||
"""
|
||||
|
||||
When I try `wp theme get myth`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
Error: Stylesheet is missing.
|
||||
"""
|
||||
|
||||
When I try `wp theme status myth`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Error: Stylesheet is missing.
|
||||
"""
|
||||
|
||||
When I run `wp theme install myth --force`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Theme updated successfully.
|
||||
"""
|
||||
|
||||
Scenario: Enabling and disabling a theme
|
||||
Given a WP multisite install
|
||||
And I run `wp theme install jolene`
|
||||
And I run `wp theme install biker`
|
||||
|
||||
When I try `wp option get allowedthemes`
|
||||
Then the return code should be 1
|
||||
And STDERR should be empty
|
||||
|
||||
When I run `wp theme enable biker`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Success: Enabled the 'Biker' theme.
|
||||
"""
|
||||
|
||||
When I run `wp option get allowedthemes`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
'biker' => true
|
||||
"""
|
||||
|
||||
When I run `wp theme disable biker`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Success: Disabled the 'Biker' theme.
|
||||
"""
|
||||
|
||||
When I run `wp option get allowedthemes`
|
||||
Then STDOUT should not contain:
|
||||
"""
|
||||
'biker' => true
|
||||
"""
|
||||
|
||||
When I run `wp theme enable biker --activate`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Success: Enabled the 'Biker' theme.
|
||||
Success: Switched to 'Biker' theme.
|
||||
"""
|
||||
|
||||
When I run `wp network-meta get 1 allowedthemes`
|
||||
Then STDOUT should not contain:
|
||||
"""
|
||||
'biker' => true
|
||||
"""
|
||||
|
||||
When I run `wp theme enable biker --network`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Success: Network enabled the 'Biker' theme.
|
||||
"""
|
||||
|
||||
When I run `wp network-meta get 1 allowedthemes`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
'biker' => true
|
||||
"""
|
||||
|
||||
When I run `wp theme disable biker --network`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Success: Network disabled the 'Biker' theme.
|
||||
"""
|
||||
|
||||
When I run `wp network-meta get 1 allowedthemes`
|
||||
Then STDOUT should not contain:
|
||||
"""
|
||||
'biker' => true
|
||||
"""
|
||||
|
||||
Scenario: Enabling and disabling a theme without multisite
|
||||
Given a WP install
|
||||
|
||||
When I try `wp theme enable p2`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Error: This is not a multisite install.
|
||||
"""
|
||||
|
||||
When I try `wp theme disable p2`
|
||||
Then STDERR should be:
|
||||
"""
|
||||
Error: This is not a multisite install.
|
||||
"""
|
||||
|
||||
Scenario: Install a theme, then update to a specific version of that theme
|
||||
Given a WP install
|
||||
|
||||
When I run `wp theme install p2 --version=1.4.1`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp theme update p2 --version=1.4.2`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp theme list --fields=name,version`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | version |
|
||||
| p2 | 1.4.2 |
|
||||
|
||||
Scenario: Install and attempt to activate a child theme without its parent
|
||||
Given a WP install
|
||||
And I run `wp theme install biker`
|
||||
And I run `rm -rf wp-content/themes/jolene`
|
||||
|
||||
When I try `wp theme activate biker`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
Error: The parent theme is missing. Please install the "jolene" parent theme.
|
||||
"""
|
||||
|
||||
Scenario: List an active theme with its parent
|
||||
Given a WP install
|
||||
And I run `wp theme install jolene`
|
||||
And I run `wp theme install --activate biker`
|
||||
|
||||
When I run `wp theme list --fields=name,status`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status |
|
||||
| biker | active |
|
||||
| jolene | parent |
|
||||
|
||||
Scenario: When updating a theme --format should be the same when using --dry-run
|
||||
Given a WP install
|
||||
|
||||
When I run `wp theme install --force twentytwelve --version=1.0`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp theme list --name=twentytwelve --field=update_version`
|
||||
And save STDOUT as {UPDATE_VERSION}
|
||||
|
||||
When I run `wp theme update twentytwelve --format=summary --dry-run`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Available theme updates:
|
||||
Twenty Twelve update from version 1.0 to version {UPDATE_VERSION}
|
||||
"""
|
||||
|
||||
When I run `wp theme update twentytwelve --format=json --dry-run`
|
||||
Then STDOUT should be JSON containing:
|
||||
"""
|
||||
[{"name":"twentytwelve","status":"inactive","version":"1.0","update_version":"{UPDATE_VERSION}"}]
|
||||
"""
|
||||
|
||||
When I run `wp theme update twentytwelve --format=csv --dry-run`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
name,status,version,update_version
|
||||
twentytwelve,inactive,1.0,{UPDATE_VERSION}
|
||||
"""
|
||||
|
||||
Scenario: Check json and csv formats when updating a theme
|
||||
Given a WP install
|
||||
|
||||
When I run `wp theme install --force twentytwelve --version=1.0`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp theme list --name=twentytwelve --field=update_version`
|
||||
And save STDOUT as {UPDATE_VERSION}
|
||||
|
||||
When I run `wp theme update twentytwelve --format=json`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
[{"name":"twentytwelve","old_version":"1.0","new_version":"{UPDATE_VERSION}","status":"Updated"}]
|
||||
"""
|
||||
|
||||
When I run `wp theme install --force twentytwelve --version=1.0`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp theme update twentytwelve --format=csv`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
name,old_version,new_version,status
|
||||
twentytwelve,1.0,{UPDATE_VERSION},Updated
|
||||
"""
|
||||
|
||||
Scenario: Automatically install parent theme for a child theme
|
||||
Given a WP install
|
||||
|
||||
When I try `wp theme status stargazer`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
Error: The 'stargazer' theme could not be found.
|
||||
"""
|
||||
|
||||
When I run `wp theme install buntu`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
This theme requires a parent theme. Checking if it is installed
|
||||
"""
|
||||
|
||||
When I run `wp theme status stargazer`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Theme stargazer details:
|
||||
"""
|
||||
And STDERR should be empty
|
|
@ -1,187 +0,0 @@
|
|||
Feature: Manage WordPress themes and plugins
|
||||
|
||||
Background:
|
||||
Given an empty cache
|
||||
|
||||
Scenario Outline: Installing, upgrading and deleting a theme or plugin
|
||||
Given a WP install
|
||||
And I run `wp <type> path`
|
||||
And save STDOUT as {CONTENT_DIR}
|
||||
|
||||
When I try `wp <type> is-installed <item>`
|
||||
Then the return code should be 1
|
||||
And STDERR should be empty
|
||||
|
||||
When I try `wp <type> get <item>`
|
||||
Then the return code should be 1
|
||||
And STDERR should not be empty
|
||||
|
||||
# Install an out of date <item> from WordPress.org repository
|
||||
When I run `wp <type> install <item> --version=<version>`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
<type_name> installed successfully
|
||||
"""
|
||||
And the {SUITE_CACHE_DIR}/<type>/<item>-<version>.zip file should exist
|
||||
|
||||
When I try `wp <type> is-installed <item>`
|
||||
Then the return code should be 0
|
||||
|
||||
When I run `wp <type> get <item>`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| Field | Value |
|
||||
| title | <item_title> |
|
||||
|
||||
When I run `wp <type> get <item> --field=title`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
<item_title>
|
||||
"""
|
||||
|
||||
When I run `wp <type> get <item> --field=title --format=json`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
"<item_title>"
|
||||
"""
|
||||
|
||||
When I run `wp <type> list`
|
||||
Then STDOUT should be a table containing rows:
|
||||
| name | status | update | version |
|
||||
| <item> | inactive | available | <version> |
|
||||
|
||||
When I run `wp <type> list --field=name`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
<item>
|
||||
"""
|
||||
|
||||
When I run `wp <type> list --field=name --format=json`
|
||||
Then STDOUT should be a JSON array containing:
|
||||
"""
|
||||
["<item>"]
|
||||
"""
|
||||
|
||||
When I run `wp <type> status`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
U = Update Available
|
||||
"""
|
||||
|
||||
When I run `wp <type> status <item>`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Status: Inactive
|
||||
Version: <version> (Update available)
|
||||
"""
|
||||
|
||||
When I run `wp <type> update <item>`
|
||||
And save STDOUT 'Downloading update from .*\/<item>\.%s\.zip' as {NEW_VERSION}
|
||||
And STDOUT should not be empty
|
||||
Then STDOUT should not contain:
|
||||
"""
|
||||
Error
|
||||
"""
|
||||
And the {SUITE_CACHE_DIR}/<type>/<item>-{NEW_VERSION}.zip file should exist
|
||||
|
||||
When I run `wp <type> update --all`
|
||||
Then STDOUT should not be empty
|
||||
|
||||
When I run `wp <type> status <item>`
|
||||
Then STDOUT should not contain:
|
||||
"""
|
||||
(Update available)
|
||||
"""
|
||||
|
||||
When I run `wp <type> delete <item>`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Deleted '<item>' <type>.
|
||||
"""
|
||||
|
||||
When I try `wp <type> status <item>`
|
||||
Then the return code should be 1
|
||||
And STDERR should not be empty
|
||||
|
||||
|
||||
# Install and update <item> from cache
|
||||
When I run `wp <type> install <item> --version=<version>`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Using cached file '{SUITE_CACHE_DIR}/<type>/<item>-<version>.zip'...
|
||||
"""
|
||||
|
||||
When I run `wp <type> update <item>`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Using cached file '{SUITE_CACHE_DIR}/<type>/<item>-{NEW_VERSION}.zip'...
|
||||
"""
|
||||
|
||||
When I run `wp <type> delete <item>`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Deleted '<item>' <type>.
|
||||
"""
|
||||
And the <file_to_check> file should not exist
|
||||
|
||||
|
||||
# Install <item> from a local zip file
|
||||
When I run `wp <type> install {SUITE_CACHE_DIR}/<type>/<item>-<version>.zip`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
<type_name> installed successfully.
|
||||
"""
|
||||
And the <file_to_check> file should exist
|
||||
|
||||
When I run `wp <type> delete <item>`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Deleted '<item>' <type>.
|
||||
"""
|
||||
And the <file_to_check> file should not exist
|
||||
|
||||
# Install <item> from a remote zip file (standard URL with no GET parameters)
|
||||
When I run `wp <type> install <zip_file>`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
<type_name> installed successfully.
|
||||
"""
|
||||
And the <file_to_check> file should exist
|
||||
|
||||
When I run `wp <type> delete <item>`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Deleted '<item>' <type>.
|
||||
"""
|
||||
And the <file_to_check> file should not exist
|
||||
|
||||
# Install <item> from a remote zip file (complex URL with GET parameters)
|
||||
When I run `wp <type> install '<zip_file>?AWSAccessKeyId=123&Expires=456&Signature=abcdef'`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
<type_name> installed successfully.
|
||||
"""
|
||||
And the <file_to_check> file should exist
|
||||
|
||||
When I run `wp <type> delete <item>`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Deleted '<item>' <type>.
|
||||
"""
|
||||
And the <file_to_check> file should not exist
|
||||
|
||||
When I run `wp <type> search <item> --per-page=2 --fields=name,slug`
|
||||
Then STDOUT should contain:
|
||||
"""
|
||||
Showing 2 of
|
||||
"""
|
||||
|
||||
When I try `wp <type> install an-impossible-slug-because-abc3fr`
|
||||
Then STDERR should contain:
|
||||
"""
|
||||
Warning: Couldn't find 'an-impossible-slug-because-abc3fr' in the WordPress.org <type> directory.
|
||||
"""
|
||||
|
||||
Examples:
|
||||
| type | type_name | item | item_title | version | zip_file | file_to_check |
|
||||
| theme | Theme | p2 | P2 | 1.0.1 | https://wordpress.org/themes/download/p2.1.0.1.zip | {CONTENT_DIR}/p2/style.css |
|
||||
| plugin | Plugin | category-checklist-tree | Category Checklist Tree | 1.2 | https://downloads.wordpress.org/plugin/category-checklist-tree.1.2.zip | {CONTENT_DIR}/category-checklist-tree/category-checklist-tree.php |
|
|
@ -1,501 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace WP_CLI;
|
||||
|
||||
use WP_CLI;
|
||||
use WP_CLI\Utils;
|
||||
|
||||
abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||
|
||||
protected $item_type;
|
||||
protected $obj_fields;
|
||||
|
||||
protected $upgrade_refresh;
|
||||
protected $upgrade_transient;
|
||||
|
||||
protected $chained_command = false;
|
||||
|
||||
function __construct() {
|
||||
// Do not automatically check translations updates after updating plugins/themes.
|
||||
add_action( 'upgrader_process_complete', function() {
|
||||
remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
|
||||
}, 1 );
|
||||
}
|
||||
|
||||
abstract protected function get_upgrader_class( $force );
|
||||
|
||||
abstract protected function get_item_list();
|
||||
|
||||
/**
|
||||
* @param array List of update candidates
|
||||
* @param array List of item names
|
||||
* @return array List of update candidates
|
||||
*/
|
||||
abstract protected function filter_item_list( $items, $args );
|
||||
|
||||
abstract protected function get_all_items();
|
||||
|
||||
abstract protected function get_status( $file );
|
||||
|
||||
abstract protected function status_single( $args );
|
||||
|
||||
abstract protected function install_from_repo( $slug, $assoc_args );
|
||||
|
||||
function status( $args ) {
|
||||
// Force WordPress to check for updates
|
||||
call_user_func( $this->upgrade_refresh );
|
||||
|
||||
if ( empty( $args ) ) {
|
||||
$this->status_all();
|
||||
} else {
|
||||
$this->status_single( $args );
|
||||
}
|
||||
}
|
||||
|
||||
private function status_all() {
|
||||
$items = $this->get_all_items();
|
||||
|
||||
$n = count( $items );
|
||||
|
||||
// Not interested in the translation, just the number logic
|
||||
\WP_CLI::log( sprintf( _n(
|
||||
"%d installed {$this->item_type}:",
|
||||
"%d installed {$this->item_type}s:",
|
||||
$n ), $n ) );
|
||||
|
||||
$padding = $this->get_padding($items);
|
||||
|
||||
foreach ( $items as $file => $details ) {
|
||||
if ( $details['update'] ) {
|
||||
$line = ' %yU%n';
|
||||
} else {
|
||||
$line = ' ';
|
||||
}
|
||||
|
||||
$line .= $this->format_status( $details['status'], 'short' );
|
||||
$line .= " " . str_pad( $details['name'], $padding ). "%n";
|
||||
if ( !empty( $details['version'] ) ) {
|
||||
$line .= " " . $details['version'];
|
||||
}
|
||||
|
||||
\WP_CLI::line( \WP_CLI::colorize( $line ) );
|
||||
}
|
||||
|
||||
\WP_CLI::line();
|
||||
|
||||
$this->show_legend( $items );
|
||||
}
|
||||
|
||||
private function get_padding( $items ) {
|
||||
$max_len = 0;
|
||||
|
||||
foreach ( $items as $details ) {
|
||||
$len = strlen( $details['name'] );
|
||||
|
||||
if ( $len > $max_len ) {
|
||||
$max_len = $len;
|
||||
}
|
||||
}
|
||||
|
||||
return $max_len;
|
||||
}
|
||||
|
||||
private function show_legend( $items ) {
|
||||
$statuses = array_unique( wp_list_pluck( $items, 'status' ) );
|
||||
|
||||
$legend_line = array();
|
||||
|
||||
foreach ( $statuses as $status ) {
|
||||
$legend_line[] = sprintf( '%s%s = %s%%n',
|
||||
$this->get_color( $status ),
|
||||
$this->map['short'][ $status ],
|
||||
$this->map['long'][ $status ]
|
||||
);
|
||||
}
|
||||
|
||||
if ( in_array( true, wp_list_pluck( $items, 'update' ) ) )
|
||||
$legend_line[] = '%yU = Update Available%n';
|
||||
|
||||
\WP_CLI::line( 'Legend: ' . \WP_CLI::colorize( implode( ', ', $legend_line ) ) );
|
||||
}
|
||||
|
||||
function install( $args, $assoc_args ) {
|
||||
|
||||
$successes = $errors = 0;
|
||||
foreach ( $args as $slug ) {
|
||||
|
||||
if ( empty( $slug ) ) {
|
||||
WP_CLI::warning( "Ignoring ambigious empty slug value." );
|
||||
continue;
|
||||
}
|
||||
|
||||
$local_or_remote_zip_file = false;
|
||||
$result = false;
|
||||
|
||||
// Check if a URL to a remote or local zip has been specified
|
||||
if ( strpos( $slug, '://' ) !== false || ( pathinfo( $slug, PATHINFO_EXTENSION ) === 'zip' && is_file( $slug ) ) ) {
|
||||
$local_or_remote_zip_file = $slug;
|
||||
}
|
||||
|
||||
if ( $local_or_remote_zip_file ) {
|
||||
// Install from local or remote zip file
|
||||
$file_upgrader = $this->get_upgrader( $assoc_args );
|
||||
|
||||
$filter = false;
|
||||
if ( strpos( $local_or_remote_zip_file, '://' ) !== false
|
||||
&& 'github.com' === parse_url( $local_or_remote_zip_file, PHP_URL_HOST ) ) {
|
||||
$filter = function( $source, $remote_source, $upgrader ) use ( $local_or_remote_zip_file ) {
|
||||
// Don't attempt to rename ZIPs uploaded to the releases page
|
||||
if ( preg_match( '#github\.com/([^/]+)/([^/]+)/releases/download/#', $local_or_remote_zip_file ) || preg_match( '#github\.com/([^/]+)/([^/]+)/raw/#', $local_or_remote_zip_file ) ) {
|
||||
return $source;
|
||||
}
|
||||
$branch_length = strlen( pathinfo( $local_or_remote_zip_file, PATHINFO_FILENAME ) );
|
||||
if ( $branch_length ) {
|
||||
$new_path = substr( rtrim( $source, '/' ), 0, - ( $branch_length + 1 ) ) . '/';
|
||||
if ( $GLOBALS['wp_filesystem']->move( $source, $new_path ) ) {
|
||||
WP_CLI::log( "Renamed Github-based project from '" . Utils\basename( $source ) . "' to '" . Utils\basename( $new_path ) . "'." );
|
||||
return $new_path;
|
||||
} else {
|
||||
return new \WP_Error( 'wpcli_install_gitub', "Couldn't move Github-based project to appropriate directory." );
|
||||
}
|
||||
}
|
||||
return $source;
|
||||
};
|
||||
add_filter( 'upgrader_source_selection', $filter, 10, 3 );
|
||||
}
|
||||
|
||||
if ( $file_upgrader->install( $local_or_remote_zip_file ) ) {
|
||||
$slug = $file_upgrader->result['destination_name'];
|
||||
$result = true;
|
||||
if ( $filter ) {
|
||||
remove_filter( 'upgrader_source_selection', $filter, 10 );
|
||||
}
|
||||
$successes++;
|
||||
} else {
|
||||
$errors++;
|
||||
}
|
||||
} else {
|
||||
// Assume a plugin/theme slug from the WordPress.org repository has been specified
|
||||
$result = $this->install_from_repo( $slug, $assoc_args );
|
||||
|
||||
if ( is_null( $result ) ) {
|
||||
$errors++;
|
||||
} elseif ( is_wp_error( $result ) ) {
|
||||
$key = $result->get_error_code();
|
||||
if ( in_array( $key, array( 'plugins_api_failed', 'themes_api_failed' ) )
|
||||
&& ! empty( $result->error_data[ $key ] ) && in_array( $result->error_data[ $key ], array( 'N;', 'b:0;' ) ) ) {
|
||||
\WP_CLI::warning( "Couldn't find '$slug' in the WordPress.org {$this->item_type} directory." );
|
||||
$errors++;
|
||||
} else {
|
||||
\WP_CLI::warning( "$slug: " . $result->get_error_message() );
|
||||
if ( 'already_installed' !== $key ) {
|
||||
$errors++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$successes++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $result ) {
|
||||
$this->chained_command = true;
|
||||
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'activate-network' ) ) {
|
||||
\WP_CLI::log( "Network-activating '$slug'..." );
|
||||
$this->activate( array( $slug ), array( 'network' => true ) );
|
||||
}
|
||||
|
||||
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'activate' ) ) {
|
||||
\WP_CLI::log( "Activating '$slug'..." );
|
||||
$this->activate( array( $slug ) );
|
||||
}
|
||||
$this->chained_command = false;
|
||||
}
|
||||
}
|
||||
Utils\report_batch_operation_results( $this->item_type, 'install', count( $args ), $successes, $errors );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare an API response for downloading a particular version of an item.
|
||||
*
|
||||
* @param object $response wordpress.org API response
|
||||
* @param string $version The desired version of the package
|
||||
*/
|
||||
protected static function alter_api_response( $response, $version ) {
|
||||
if ( $response->version == $version )
|
||||
return;
|
||||
|
||||
// WordPress.org forces https, but still sometimes returns http
|
||||
// See https://twitter.com/nacin/status/512362694205140992
|
||||
$response->download_link = str_replace( 'http://', 'https://', $response->download_link );
|
||||
|
||||
list( $link ) = explode( $response->slug, $response->download_link );
|
||||
|
||||
if ( false !== strpos( $response->download_link, '/theme/' ) )
|
||||
$download_type = 'theme';
|
||||
else if ( false !== strpos( $response->download_link, '/plugin/' ) )
|
||||
$download_type = 'plugin';
|
||||
else
|
||||
$download_type = 'plugin/theme';
|
||||
|
||||
if ( 'dev' == $version ) {
|
||||
$response->download_link = $link . $response->slug . '.zip';
|
||||
$response->version = 'Development Version';
|
||||
} else {
|
||||
$response->download_link = $link . $response->slug . '.' . $version .'.zip';
|
||||
$response->version = $version;
|
||||
|
||||
// check if the requested version exists
|
||||
$response = wp_remote_head( $response->download_link );
|
||||
$response_code = wp_remote_retrieve_response_code( $response );
|
||||
if ( 200 !== $response_code ) {
|
||||
\WP_CLI::error( sprintf(
|
||||
"Can't find the requested %s's version %s in the WordPress.org %s repository (HTTP code %d).",
|
||||
$download_type, $version, $download_type, $response_code ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function get_upgrader( $assoc_args ) {
|
||||
$upgrader_class = $this->get_upgrader_class( \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) );
|
||||
return \WP_CLI\Utils\get_upgrader( $upgrader_class );
|
||||
}
|
||||
|
||||
protected function update_many( $args, $assoc_args ) {
|
||||
call_user_func( $this->upgrade_refresh );
|
||||
|
||||
if ( ! empty( $assoc_args['format'] ) && in_array( $assoc_args['format'], array( 'json', 'csv' ) ) ) {
|
||||
$logger = new \WP_CLI\Loggers\Quiet;
|
||||
\WP_CLI::set_logger( $logger );
|
||||
}
|
||||
|
||||
if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) {
|
||||
\WP_CLI::error( "Please specify one or more {$this->item_type}s, or use --all." );
|
||||
}
|
||||
|
||||
$items = $this->get_item_list();
|
||||
|
||||
$errors = 0;
|
||||
if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) {
|
||||
$items = $this->filter_item_list( $items, $args );
|
||||
$errors = count( $args ) - count( $items );
|
||||
}
|
||||
|
||||
$items_to_update = wp_list_filter( $items, array(
|
||||
'update' => true
|
||||
) );
|
||||
|
||||
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'dry-run' ) ) {
|
||||
if ( empty( $items_to_update ) ) {
|
||||
\WP_CLI::line( "No {$this->item_type} updates available." );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! empty( $assoc_args['format'] ) && in_array( $assoc_args['format'], array( 'json', 'csv' ) ) ) {
|
||||
\WP_CLI\Utils\format_items( $assoc_args['format'], $items_to_update, array( 'name', 'status', 'version', 'update_version' ) );
|
||||
} else if ( ! empty( $assoc_args['format'] ) && 'summary' === $assoc_args['format'] ) {
|
||||
\WP_CLI::line( "Available {$this->item_type} updates:" );
|
||||
foreach( $items_to_update as $item_to_update => $info ) {
|
||||
\WP_CLI::log( "{$info['title']} update from version {$info['version']} to version {$info['update_version']}" );
|
||||
}
|
||||
} else {
|
||||
\WP_CLI::line( "Available {$this->item_type} updates:" );
|
||||
\WP_CLI\Utils\format_items( 'table', $items_to_update, array( 'name', 'status', 'version', 'update_version' ) );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
|
||||
// Only attempt to update if there is something to update
|
||||
if ( !empty( $items_to_update ) ) {
|
||||
$cache_manager = \WP_CLI::get_http_cache_manager();
|
||||
foreach ($items_to_update as $item) {
|
||||
$cache_manager->whitelist_package($item['update_package'], $this->item_type, $item['name'], $item['update_version']);
|
||||
}
|
||||
$upgrader = $this->get_upgrader( $assoc_args );
|
||||
$result = $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) );
|
||||
}
|
||||
|
||||
// Let the user know the results.
|
||||
$num_to_update = count( $items_to_update );
|
||||
$num_updated = count( array_filter( $result ) );
|
||||
|
||||
if ( $num_to_update > 0 ) {
|
||||
if ( ! empty( $assoc_args['format'] ) && 'summary' === $assoc_args['format'] ) {
|
||||
foreach( $items_to_update as $item_to_update => $info ) {
|
||||
$message = $result[ $info['update_id'] ] !== null ? 'updated successfully' : 'did not update';
|
||||
\WP_CLI::log( "{$info['title']} {$message} from version {$info['version']} to version {$info['update_version']}" );
|
||||
}
|
||||
} else {
|
||||
$status = array();
|
||||
foreach($items_to_update as $item_to_update => $info) {
|
||||
$status[$item_to_update] = array(
|
||||
'name' => $info['name'],
|
||||
'old_version' => $info['version'],
|
||||
'new_version' => $info['update_version'],
|
||||
'status' => $result[ $info['update_id'] ] !== null ? 'Updated' : 'Error',
|
||||
);
|
||||
}
|
||||
|
||||
$format = 'table';
|
||||
if ( ! empty( $assoc_args['format'] ) && in_array( $assoc_args['format'], array( 'json', 'csv' ) ) ) {
|
||||
$format = $assoc_args['format'];
|
||||
}
|
||||
|
||||
\WP_CLI\Utils\format_items( $format, $status, array( 'name', 'old_version', 'new_version', 'status' ) );
|
||||
}
|
||||
}
|
||||
Utils\report_batch_operation_results( $this->item_type, 'update', count( $args ), $num_updated, $errors );
|
||||
}
|
||||
|
||||
protected function _list( $_, $assoc_args ) {
|
||||
// Force WordPress to check for updates
|
||||
call_user_func( $this->upgrade_refresh );
|
||||
|
||||
$all_items = $this->get_all_items();
|
||||
if ( !is_array( $all_items ) )
|
||||
\WP_CLI::error( "No {$this->item_type}s found." );
|
||||
|
||||
foreach ( $all_items as $key => &$item ) {
|
||||
|
||||
if ( empty( $item['version'] ) )
|
||||
$item['version'] = '';
|
||||
|
||||
foreach ( $item as $field => &$value ) {
|
||||
if ( $value === true ) {
|
||||
$value = 'available';
|
||||
} else if ( $value === false ) {
|
||||
$value = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $this->obj_fields as $field ) {
|
||||
if ( isset( $assoc_args[$field] )
|
||||
&& $assoc_args[$field] != $item[$field] )
|
||||
unset( $all_items[$key] );
|
||||
}
|
||||
}
|
||||
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
$formatter->display_items( $all_items );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether an item has an update available or not.
|
||||
*
|
||||
* @param string $slug The plugin/theme slug
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function has_update( $slug ) {
|
||||
$update_list = get_site_transient( $this->upgrade_transient );
|
||||
|
||||
return isset( $update_list->response[ $slug ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the available update info
|
||||
*
|
||||
* @param string $slug The plugin/theme slug
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
protected function get_update_info( $slug ) {
|
||||
$update_list = get_site_transient( $this->upgrade_transient );
|
||||
|
||||
if ( !isset( $update_list->response[ $slug ] ) )
|
||||
return null;
|
||||
|
||||
return (array) $update_list->response[ $slug ];
|
||||
}
|
||||
|
||||
private $map = array(
|
||||
'short' => array(
|
||||
'inactive' => 'I',
|
||||
'active' => 'A',
|
||||
'active-network' => 'N',
|
||||
'must-use' => 'M',
|
||||
'parent' => 'P',
|
||||
),
|
||||
'long' => array(
|
||||
'inactive' => 'Inactive',
|
||||
'active' => 'Active',
|
||||
'active-network' => 'Network Active',
|
||||
'must-use' => 'Must Use',
|
||||
'parent' => 'Parent',
|
||||
)
|
||||
);
|
||||
|
||||
protected function format_status( $status, $format ) {
|
||||
return $this->get_color( $status ) . $this->map[ $format ][ $status ];
|
||||
}
|
||||
|
||||
private function get_color( $status ) {
|
||||
static $colors = array(
|
||||
'inactive' => '',
|
||||
'active' => '%g',
|
||||
'active-network' => '%g',
|
||||
'must-use' => '%c',
|
||||
'parent' => '%p',
|
||||
);
|
||||
|
||||
return $colors[ $status ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Search wordpress.org repo.
|
||||
*
|
||||
* @param array $args A arguments array containing the search term in the first element.
|
||||
* @param array $assoc_args Data passed in from command.
|
||||
*/
|
||||
protected function _search( $args, $assoc_args ) {
|
||||
$term = $args[0];
|
||||
|
||||
$defaults = array(
|
||||
'per-page' => 10,
|
||||
'page' => 1,
|
||||
'fields' => implode( ',', array( 'name', 'slug', 'rating' ) ),
|
||||
);
|
||||
$assoc_args = array_merge( $defaults, $assoc_args );
|
||||
$fields = array();
|
||||
foreach( explode( ',', $assoc_args['fields'] ) as $field ) {
|
||||
$fields[ $field ] = true;
|
||||
}
|
||||
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
|
||||
$api_args = array(
|
||||
'per_page' => (int) $assoc_args['per-page'],
|
||||
'page' => (int) $assoc_args['page'],
|
||||
'search' => $term,
|
||||
'fields' => $fields,
|
||||
);
|
||||
|
||||
if ( 'plugin' == $this->item_type ) {
|
||||
$api = plugins_api( 'query_plugins', $api_args );
|
||||
} else {
|
||||
$api = themes_api( 'query_themes', $api_args );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $api ) )
|
||||
\WP_CLI::error( $api->get_error_message() . __( ' Try again' ) );
|
||||
|
||||
$plural = $this->item_type . 's';
|
||||
|
||||
if ( ! isset( $api->$plural ) )
|
||||
\WP_CLI::error( __( 'API error. Try Again.' ) );
|
||||
|
||||
$items = $api->$plural;
|
||||
|
||||
$count = \WP_CLI\Utils\get_flag_value( $api->info, 'results', 'unknown' );
|
||||
\WP_CLI::success( sprintf( 'Showing %s of %s %s.', count( $items ), $count, $plural ) );
|
||||
|
||||
$formatter->display_items( $items );
|
||||
}
|
||||
|
||||
protected function get_formatter( &$assoc_args ) {
|
||||
return new \WP_CLI\Formatter( $assoc_args, $this->obj_fields, $this->item_type );
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace WP_CLI;
|
||||
|
||||
/**
|
||||
* A plugin upgrader class that clears the destination directory.
|
||||
*/
|
||||
class DestructivePluginUpgrader extends \Plugin_Upgrader {
|
||||
|
||||
function install_package( $args = array() ) {
|
||||
parent::upgrade_strings(); // needed for the 'remove_old' string
|
||||
|
||||
$args['clear_destination'] = true;
|
||||
$args['abort_if_destination_exists'] = false;
|
||||
return parent::install_package( $args );
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace WP_CLI;
|
||||
|
||||
/**
|
||||
* A theme upgrader class that clears the destination directory.
|
||||
*/
|
||||
class DestructiveThemeUpgrader extends \Theme_Upgrader {
|
||||
|
||||
function install_package( $args = array() ) {
|
||||
parent::upgrade_strings(); // needed for the 'remove_old' string
|
||||
|
||||
$args['clear_destination'] = true;
|
||||
$args['abort_if_destination_exists'] = false;
|
||||
return parent::install_package( $args );
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace WP_CLI\Fetchers;
|
||||
|
||||
/**
|
||||
* Fetch a WordPress plugin based on one of its attributes.
|
||||
*/
|
||||
class Plugin extends Base {
|
||||
|
||||
/**
|
||||
* @var string $msg Error message to use when invalid data is provided
|
||||
*/
|
||||
protected $msg = "The '%s' plugin could not be found.";
|
||||
|
||||
/**
|
||||
* Get a plugin object by name
|
||||
*
|
||||
* @param string $name
|
||||
* @return object|false
|
||||
*/
|
||||
public function get( $name ) {
|
||||
foreach ( get_plugins() as $file => $_ ) {
|
||||
if ( $file === "$name.php" ||
|
||||
( $name && $file === $name ) ||
|
||||
( dirname( $file ) === $name && $name !== '.' ) ) {
|
||||
return (object) compact( 'name', 'file' );
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace WP_CLI\Fetchers;
|
||||
|
||||
/**
|
||||
* Fetch a WordPress theme based on one of its attributes.
|
||||
*/
|
||||
class Theme extends Base {
|
||||
|
||||
/**
|
||||
* @var string $msg Error message to use when invalid data is provided
|
||||
*/
|
||||
protected $msg = "The '%s' theme could not be found.";
|
||||
|
||||
/**
|
||||
* Get a theme object by name
|
||||
*
|
||||
* @param string $name
|
||||
* @return object|false
|
||||
*/
|
||||
public function get( $name ) {
|
||||
$theme = wp_get_theme( $name );
|
||||
|
||||
if ( !$theme->exists() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $theme;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,993 +0,0 @@
|
|||
<?php
|
||||
|
||||
use \WP_CLI\Utils;
|
||||
|
||||
/**
|
||||
* Manage plugins.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Activate plugin
|
||||
* $ wp plugin activate hello-dolly
|
||||
* Plugin 'hello-dolly' activated.
|
||||
* Success: Activated 1 of 1 plugins.
|
||||
*
|
||||
* # Deactivate plugin
|
||||
* $ wp plugin deactivate hello-dolly
|
||||
* Plugin 'hello-dolly' deactivated.
|
||||
* Success: Deactivated 1 of 1 plugins.
|
||||
*
|
||||
* # Delete plugin
|
||||
* $ wp plugin delete hello-dolly
|
||||
* Deleted 'hello-dolly' plugin.
|
||||
* Success: Deleted 1 of 1 plugins.
|
||||
*
|
||||
* # Install the latest version from wordpress.org and activate
|
||||
* $ wp plugin install bbpress --activate
|
||||
* Installing bbPress (2.5.9)
|
||||
* Downloading install package from https://downloads.wordpress.org/plugin/bbpress.2.5.9.zip...
|
||||
* Using cached file '/home/vagrant/.wp-cli/cache/plugin/bbpress-2.5.9.zip'...
|
||||
* Unpacking the package...
|
||||
* Installing the plugin...
|
||||
* Plugin installed successfully.
|
||||
* Activating 'bbpress'...
|
||||
* Plugin 'bbpress' activated.
|
||||
* Success: Installed 1 of 1 plugins.
|
||||
*
|
||||
* @package wp-cli
|
||||
*/
|
||||
class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||
|
||||
protected $item_type = 'plugin';
|
||||
protected $upgrade_refresh = 'wp_update_plugins';
|
||||
protected $upgrade_transient = 'update_plugins';
|
||||
|
||||
protected $obj_fields = array(
|
||||
'name',
|
||||
'status',
|
||||
'update',
|
||||
'version'
|
||||
);
|
||||
|
||||
function __construct() {
|
||||
require_once ABSPATH.'wp-admin/includes/plugin.php';
|
||||
require_once ABSPATH.'wp-admin/includes/plugin-install.php';
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->fetcher = new \WP_CLI\Fetchers\Plugin;
|
||||
}
|
||||
|
||||
protected function get_upgrader_class( $force ) {
|
||||
return $force ? '\\WP_CLI\\DestructivePluginUpgrader' : 'Plugin_Upgrader';
|
||||
}
|
||||
|
||||
/**
|
||||
* See the status of one or all plugins.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [<plugin>]
|
||||
* : A particular plugin to show the status for.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Displays status of all plugins
|
||||
* $ wp plugin status
|
||||
* 5 installed plugins:
|
||||
* I akismet 3.1.11
|
||||
* I easy-digital-downloads 2.5.16
|
||||
* A theme-check 20160523.1
|
||||
* I wen-logo-slider 2.0.3
|
||||
* M ns-pack 1.0.0
|
||||
* Legend: I = Inactive, A = Active, M = Must Use
|
||||
*
|
||||
* # Displays status of a plugin
|
||||
* $ wp plugin status theme-check
|
||||
* Plugin theme-check details:
|
||||
* Name: Theme Check
|
||||
* Status: Active
|
||||
* Version: 20160523.1
|
||||
* Author: Otto42, pross
|
||||
* Description: A simple and easy way to test your theme for all the latest WordPress standards and practices. A great theme development tool!
|
||||
*/
|
||||
public function status( $args ) {
|
||||
parent::status( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the WordPress.org plugin directory.
|
||||
*
|
||||
* Displays plugins in the WordPress.org plugin directory matching a given
|
||||
* search query.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <search>
|
||||
* : The string to search for.
|
||||
*
|
||||
* [--page=<page>]
|
||||
* : Optional page to display.
|
||||
* ---
|
||||
* default: 1
|
||||
* ---
|
||||
*
|
||||
* [--per-page=<per-page>]
|
||||
* : Optional number of results to display.
|
||||
* ---
|
||||
* default: 10
|
||||
* ---
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Prints the value of a single field for each plugin.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Ask for specific fields from the API. Defaults to name,slug,author_profile,rating. Acceptable values:
|
||||
*
|
||||
* **name**: Plugin Name
|
||||
* **slug**: Plugin Slug
|
||||
* **version**: Current Version Number
|
||||
* **author**: Plugin Author
|
||||
* **author_profile**: Plugin Author Profile
|
||||
* **contributors**: Plugin Contributors
|
||||
* **requires**: Plugin Minimum Requirements
|
||||
* **tested**: Plugin Tested Up To
|
||||
* **compatibility**: Plugin Compatible With
|
||||
* **rating**: Plugin Rating
|
||||
* **num_ratings**: Number of Plugin Ratings
|
||||
* **homepage**: Plugin Author's Homepage
|
||||
* **description**: Plugin's Description
|
||||
* **short_description**: Plugin's Short Description
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Render output in a particular format.
|
||||
* ---
|
||||
* default: table
|
||||
* options:
|
||||
* - table
|
||||
* - csv
|
||||
* - count
|
||||
* - json
|
||||
* - yaml
|
||||
* ---
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* $ wp plugin search dsgnwrks --per-page=20 --format=json
|
||||
* Success: Showing 3 of 3 plugins.
|
||||
* [{"name":"DsgnWrks Instagram Importer Debug","slug":"dsgnwrks-instagram-importer-debug","rating":0},{"name":"DsgnWrks Instagram Importer","slug":"dsgnwrks-instagram-importer","rating":84},{"name":"DsgnWrks Twitter Importer","slug":"dsgnwrks-twitter-importer","rating":80}]
|
||||
*
|
||||
* $ wp plugin search dsgnwrks --fields=name,version,slug,rating,num_ratings
|
||||
* Success: Showing 3 of 3 plugins.
|
||||
* +-----------------------------------+---------+-----------------------------------+--------+-------------+
|
||||
* | name | version | slug | rating | num_ratings |
|
||||
* +-----------------------------------+---------+-----------------------------------+--------+-------------+
|
||||
* | DsgnWrks Instagram Importer Debug | 0.1.6 | dsgnwrks-instagram-importer-debug | 0 | 0 |
|
||||
* | DsgnWrks Instagram Importer | 1.3.7 | dsgnwrks-instagram-importer | 84 | 23 |
|
||||
* | DsgnWrks Twitter Importer | 1.1.1 | dsgnwrks-twitter-importer | 80 | 1 |
|
||||
* +-----------------------------------+---------+-----------------------------------+--------+-------------+
|
||||
*/
|
||||
public function search( $args, $assoc_args ) {
|
||||
parent::_search( $args, $assoc_args );
|
||||
}
|
||||
|
||||
protected function status_single( $args ) {
|
||||
$plugin = $this->fetcher->get_check( $args[0] );
|
||||
$file = $plugin->file;
|
||||
|
||||
$details = $this->get_details( $file );
|
||||
|
||||
$status = $this->format_status( $this->get_status( $file ), 'long' );
|
||||
|
||||
$version = $details['Version'];
|
||||
|
||||
if ( $this->has_update( $file ) )
|
||||
$version .= ' (%gUpdate available%n)';
|
||||
|
||||
echo WP_CLI::colorize( \WP_CLI\Utils\mustache_render( 'plugin-status.mustache', array(
|
||||
'slug' => Utils\get_plugin_name( $file ),
|
||||
'status' => $status,
|
||||
'version' => $version,
|
||||
'name' => $details['Name'],
|
||||
'author' => $details['Author'],
|
||||
'description' => $details['Description']
|
||||
) ) );
|
||||
}
|
||||
|
||||
protected function get_all_items() {
|
||||
$items = $this->get_item_list();
|
||||
|
||||
foreach ( get_mu_plugins() as $file => $mu_plugin ) {
|
||||
$mu_version = '';
|
||||
if ( ! empty( $mu_plugin['Version'] ) ) {
|
||||
$mu_version = $mu_plugin['Version'];
|
||||
}
|
||||
|
||||
$items[ $file ] = array(
|
||||
'name' => Utils\get_plugin_name( $file ),
|
||||
'status' => 'must-use',
|
||||
'update' => false,
|
||||
'update_version' => NULL,
|
||||
'update_package' => NULL,
|
||||
'version' => $mu_version,
|
||||
'update_id' => '',
|
||||
'title' => '',
|
||||
'description' => '',
|
||||
);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate a plugin.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [<plugin>...]
|
||||
* : One or more plugins to activate.
|
||||
*
|
||||
* [--all]
|
||||
* : If set, all plugins will be activated.
|
||||
*
|
||||
* [--network]
|
||||
* : If set, the plugin will be activated for the entire multisite network.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Activate plugin
|
||||
* $ wp plugin activate hello-dolly
|
||||
* Plugin 'hello-dolly' activated.
|
||||
* Success: Activated 1 of 1 plugins.
|
||||
*
|
||||
* # Activate plugin in entire multisite network
|
||||
* $ wp plugin activate hello-dolly --network
|
||||
* Plugin 'hello-dolly' network activated.
|
||||
* Success: Network activated 1 of 1 plugins.
|
||||
*/
|
||||
public function activate( $args, $assoc_args = array() ) {
|
||||
$network_wide = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' );
|
||||
$all = \WP_CLI\Utils\get_flag_value( $assoc_args, 'all', false );
|
||||
|
||||
if ( $all ) {
|
||||
$args = array_map( function( $file ){
|
||||
return Utils\get_plugin_name( $file );
|
||||
}, array_keys( get_plugins() ) );
|
||||
}
|
||||
|
||||
$successes = $errors = 0;
|
||||
$plugins = $this->fetcher->get_many( $args );
|
||||
if ( count( $plugins ) < count( $args ) ) {
|
||||
$errors = count( $args ) - count( $plugins );
|
||||
}
|
||||
foreach ( $plugins as $plugin ) {
|
||||
$status = $this->get_status( $plugin->file );
|
||||
if ( $all && in_array( $status, array( 'active', 'active-network' ) ) ) {
|
||||
continue;
|
||||
}
|
||||
// Network-active is the highest level of activation status
|
||||
if ( 'active-network' === $status ) {
|
||||
WP_CLI::warning( "Plugin '{$plugin->name}' is already network active." );
|
||||
continue;
|
||||
}
|
||||
// Don't reactivate active plugins, but do let them become network-active
|
||||
if ( ! $network_wide && 'active' === $status ) {
|
||||
WP_CLI::warning( "Plugin '{$plugin->name}' is already active." );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Plugins need to be deactivated before being network activated
|
||||
if ( $network_wide && 'active' === $status ) {
|
||||
deactivate_plugins( $plugin->file, false, false );
|
||||
}
|
||||
|
||||
activate_plugin( $plugin->file, '', $network_wide );
|
||||
|
||||
$this->active_output( $plugin->name, $plugin->file, $network_wide, 'activate' );
|
||||
$successes++;
|
||||
}
|
||||
|
||||
if ( ! $this->chained_command ) {
|
||||
$verb = $network_wide ? 'network activate' : 'activate';
|
||||
Utils\report_batch_operation_results( 'plugin', $verb, count( $args ), $successes, $errors );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate a plugin.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [<plugin>...]
|
||||
* : One or more plugins to deactivate.
|
||||
*
|
||||
* [--uninstall]
|
||||
* : Uninstall the plugin after deactivation.
|
||||
*
|
||||
* [--all]
|
||||
* : If set, all plugins will be deactivated.
|
||||
*
|
||||
* [--network]
|
||||
* : If set, the plugin will be deactivated for the entire multisite network.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Deactivate plugin
|
||||
* $ wp plugin deactivate hello-dolly
|
||||
* Plugin 'hello-dolly' deactivated.
|
||||
* Success: Deactivated 1 of 1 plugins.
|
||||
*/
|
||||
public function deactivate( $args, $assoc_args = array() ) {
|
||||
$network_wide = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' );
|
||||
$disable_all = \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' );
|
||||
|
||||
if ( $disable_all ) {
|
||||
$args = array_map( function( $file ){
|
||||
return Utils\get_plugin_name( $file );
|
||||
}, array_keys( get_plugins() ) );
|
||||
}
|
||||
|
||||
$successes = $errors = 0;
|
||||
$plugins = $this->fetcher->get_many( $args );
|
||||
if ( count( $plugins ) < count( $args ) ) {
|
||||
$errors = count( $args ) - count( $plugins );
|
||||
}
|
||||
|
||||
foreach ( $plugins as $plugin ) {
|
||||
|
||||
$status = $this->get_status( $plugin->file );
|
||||
if ( $disable_all && ! in_array( $status, array( 'active', 'active-network' ) ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Network active plugins must be explicitly deactivated
|
||||
if ( ! $network_wide && 'active-network' === $status ) {
|
||||
WP_CLI::warning( "Plugin '{$plugin->name}' is network active and must be deactivated with --network flag." );
|
||||
$errors++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! in_array( $status, array( 'active', 'active-network' ) ) ) {
|
||||
WP_CLI::warning( "Plugin '{$plugin->name}' isn't active." );
|
||||
continue;
|
||||
}
|
||||
|
||||
deactivate_plugins( $plugin->file, false, $network_wide );
|
||||
|
||||
if ( ! is_network_admin() ) {
|
||||
update_option( 'recently_activated',
|
||||
array( $plugin->file => time() ) + (array) get_option( 'recently_activated' ) );
|
||||
} else {
|
||||
update_site_option( 'recently_activated',
|
||||
array( $plugin->file => time() ) + (array) get_site_option( 'recently_activated' ) );
|
||||
}
|
||||
|
||||
$this->active_output( $plugin->name, $plugin->file, $network_wide, 'deactivate' );
|
||||
$successes++;
|
||||
|
||||
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'uninstall' ) ) {
|
||||
WP_CLI::log( "Uninstalling '{$plugin->name}'..." );
|
||||
$this->chained_command = true;
|
||||
$this->uninstall( array( $plugin->name ) );
|
||||
$this->chained_command = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( ! $this->chained_command ) {
|
||||
$verb = $network_wide ? 'network deactivate' : 'deactivate';
|
||||
Utils\report_batch_operation_results( 'plugin', $verb, count( $args ), $successes, $errors );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle a plugin's activation state.
|
||||
*
|
||||
* If the plugin is active, then it will be deactivated. If the plugin is
|
||||
* inactive, then it will be activated.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <plugin>...
|
||||
* : One or more plugins to toggle.
|
||||
*
|
||||
* [--network]
|
||||
* : If set, the plugin will be toggled for the entire multisite network.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Akismet is currently activated
|
||||
* $ wp plugin toggle akismet
|
||||
* Plugin 'akismet' deactivated.
|
||||
* Success: Toggled 1 of 1 plugins.
|
||||
*
|
||||
* # Akismet is currently deactivated
|
||||
* $ wp plugin toggle akismet
|
||||
* Plugin 'akismet' activated.
|
||||
* Success: Toggled 1 of 1 plugins.
|
||||
*/
|
||||
public function toggle( $args, $assoc_args = array() ) {
|
||||
$network_wide = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' );
|
||||
|
||||
$successes = $errors = 0;
|
||||
$plugins = $this->fetcher->get_many( $args );
|
||||
if ( count( $plugins ) < count( $args ) ) {
|
||||
$errors = count( $args ) - count( $plugins );
|
||||
}
|
||||
$this->chained_command = true;
|
||||
foreach ( $plugins as $plugin ) {
|
||||
if ( $this->check_active( $plugin->file, $network_wide ) ) {
|
||||
$this->deactivate( array( $plugin->name ), $assoc_args );
|
||||
} else {
|
||||
$this->activate( array( $plugin->name ), $assoc_args );
|
||||
}
|
||||
$successes++;
|
||||
}
|
||||
$this->chained_command = false;
|
||||
Utils\report_batch_operation_results( 'plugin', 'toggle', count( $args ), $successes, $errors );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to a plugin or to the plugin directory.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [<plugin>]
|
||||
* : The plugin to get the path to. If not set, will return the path to the
|
||||
* plugins directory.
|
||||
*
|
||||
* [--dir]
|
||||
* : If set, get the path to the closest parent directory, instead of the
|
||||
* plugin file.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* $ cd $(wp plugin path) && pwd
|
||||
* /var/www/wordpress/wp-content/plugins
|
||||
*/
|
||||
public function path( $args, $assoc_args ) {
|
||||
$path = untrailingslashit( WP_PLUGIN_DIR );
|
||||
|
||||
if ( !empty( $args ) ) {
|
||||
$plugin = $this->fetcher->get_check( $args[0] );
|
||||
$path .= '/' . $plugin->file;
|
||||
|
||||
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'dir' ) )
|
||||
$path = dirname( $path );
|
||||
}
|
||||
|
||||
WP_CLI::line( $path );
|
||||
}
|
||||
|
||||
protected function install_from_repo( $slug, $assoc_args ) {
|
||||
$api = plugins_api( 'plugin_information', array( 'slug' => $slug ) );
|
||||
|
||||
if ( is_wp_error( $api ) ) {
|
||||
return $api;
|
||||
}
|
||||
|
||||
if ( isset( $assoc_args['version'] ) ) {
|
||||
self::alter_api_response( $api, $assoc_args['version'] );
|
||||
}
|
||||
|
||||
$status = install_plugin_install_status( $api );
|
||||
|
||||
if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) && 'install' != $status['status'] ) {
|
||||
// We know this will fail, so avoid a needless download of the package.
|
||||
return new WP_Error( 'already_installed', 'Plugin already installed.' );
|
||||
}
|
||||
|
||||
WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name, ENT_QUOTES ), $api->version ) );
|
||||
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'version' ) != 'dev' ) {
|
||||
WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version );
|
||||
}
|
||||
$result = $this->get_upgrader( $assoc_args )->install( $api->download_link );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update one or more plugins.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [<plugin>...]
|
||||
* : One or more plugins to update.
|
||||
*
|
||||
* [--all]
|
||||
* : If set, all plugins that have updates will be updated.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Output summary as table or summary. Defaults to table.
|
||||
*
|
||||
* [--version=<version>]
|
||||
* : If set, the plugin will be updated to the specified version.
|
||||
*
|
||||
* [--dry-run]
|
||||
* : Preview which plugins would be updated.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* $ wp plugin update bbpress --version=dev
|
||||
* Installing bbPress (Development Version)
|
||||
* Downloading install package from https://downloads.wordpress.org/plugin/bbpress.zip...
|
||||
* Unpacking the package...
|
||||
* Installing the plugin...
|
||||
* Removing the old version of the plugin...
|
||||
* Plugin updated successfully.
|
||||
* Success: Updated 1 of 2 plugins.
|
||||
*
|
||||
* $ wp plugin update --all
|
||||
* Enabling Maintenance mode...
|
||||
* Downloading update from https://downloads.wordpress.org/plugin/akismet.3.1.11.zip...
|
||||
* Unpacking the update...
|
||||
* Installing the latest version...
|
||||
* Removing the old version of the plugin...
|
||||
* Plugin updated successfully.
|
||||
* Downloading update from https://downloads.wordpress.org/plugin/nginx-champuru.3.2.0.zip...
|
||||
* Unpacking the update...
|
||||
* Installing the latest version...
|
||||
* Removing the old version of the plugin...
|
||||
* Plugin updated successfully.
|
||||
* Disabling Maintenance mode...
|
||||
* +------------------------+-------------+-------------+---------+
|
||||
* | name | old_version | new_version | status |
|
||||
* +------------------------+-------------+-------------+---------+
|
||||
* | akismet | 3.1.3 | 3.1.11 | Updated |
|
||||
* | nginx-cache-controller | 3.1.1 | 3.2.0 | Updated |
|
||||
* +------------------------+-------------+-------------+---------+
|
||||
* Success: Updated 2 of 2 plugins.
|
||||
*
|
||||
* @alias upgrade
|
||||
*/
|
||||
function update( $args, $assoc_args ) {
|
||||
if ( isset( $assoc_args['version'] ) ) {
|
||||
foreach ( $this->fetcher->get_many( $args ) as $plugin ) {
|
||||
$assoc_args['force'] = 1;
|
||||
$this->install( array( $plugin->name ), $assoc_args );
|
||||
}
|
||||
} else {
|
||||
parent::update_many( $args, $assoc_args );
|
||||
}
|
||||
}
|
||||
|
||||
protected function get_item_list() {
|
||||
$items = $duplicate_names = array();
|
||||
|
||||
foreach ( get_plugins() as $file => $details ) {
|
||||
$update_info = $this->get_update_info( $file );
|
||||
|
||||
$name = Utils\get_plugin_name( $file );
|
||||
if ( ! isset( $duplicate_names[ $name ] ) ) {
|
||||
$duplicate_names[ $name ] = array();
|
||||
}
|
||||
$duplicate_names[ $name ][] = $file;
|
||||
$items[ $file ] = array(
|
||||
'name' => $name,
|
||||
'status' => $this->get_status( $file ),
|
||||
'update' => (bool) $update_info,
|
||||
'update_version' => $update_info['new_version'],
|
||||
'update_package' => $update_info['package'],
|
||||
'version' => $details['Version'],
|
||||
'update_id' => $file,
|
||||
'title' => $details['Name'],
|
||||
'description' => $details['Description'],
|
||||
);
|
||||
}
|
||||
|
||||
foreach( $duplicate_names as $name => $files ) {
|
||||
if ( count( $files ) <= 1 ) {
|
||||
continue;
|
||||
}
|
||||
foreach( $files as $file ) {
|
||||
$items[ $file ]['name'] = str_replace( '.' . pathinfo( $file, PATHINFO_EXTENSION ), '', $file );
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
protected function filter_item_list( $items, $args ) {
|
||||
$basenames = wp_list_pluck( $this->fetcher->get_many( $args ), 'file' );
|
||||
return \WP_CLI\Utils\pick_fields( $items, $basenames );
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a plugin.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <plugin|zip|url>...
|
||||
* : A plugin slug, the path to a local zip file, or URL to a remote zip file.
|
||||
*
|
||||
* [--version=<version>]
|
||||
* : If set, get that particular version from wordpress.org, instead of the
|
||||
* stable version.
|
||||
*
|
||||
* [--force]
|
||||
* : If set, the command will overwrite any installed version of the plugin, without prompting
|
||||
* for confirmation.
|
||||
*
|
||||
* [--activate]
|
||||
* : If set, the plugin will be activated immediately after install.
|
||||
*
|
||||
* [--activate-network]
|
||||
* : If set, the plugin will be network activated immediately after install
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Install the latest version from wordpress.org and activate
|
||||
* $ wp plugin install bbpress --activate
|
||||
* Installing bbPress (2.5.9)
|
||||
* Downloading install package from https://downloads.wordpress.org/plugin/bbpress.2.5.9.zip...
|
||||
* Using cached file '/home/vagrant/.wp-cli/cache/plugin/bbpress-2.5.9.zip'...
|
||||
* Unpacking the package...
|
||||
* Installing the plugin...
|
||||
* Plugin installed successfully.
|
||||
* Activating 'bbpress'...
|
||||
* Plugin 'bbpress' activated.
|
||||
* Success: Installed 1 of 1 plugins.
|
||||
*
|
||||
* # Install the development version from wordpress.org
|
||||
* $ wp plugin install bbpress --version=dev
|
||||
* Installing bbPress (Development Version)
|
||||
* Downloading install package from https://downloads.wordpress.org/plugin/bbpress.zip...
|
||||
* Unpacking the package...
|
||||
* Installing the plugin...
|
||||
* Plugin installed successfully.
|
||||
* Success: Installed 1 of 1 plugins.
|
||||
*
|
||||
* # Install from a local zip file
|
||||
* $ wp plugin install ../my-plugin.zip
|
||||
* Unpacking the package...
|
||||
* Installing the plugin...
|
||||
* Plugin installed successfully.
|
||||
* Success: Installed 1 of 1 plugins.
|
||||
*
|
||||
* # Install from a remote zip file
|
||||
* $ wp plugin install http://s3.amazonaws.com/bucketname/my-plugin.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef
|
||||
* Downloading install package from http://s3.amazonaws.com/bucketname/my-plugin.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef
|
||||
* Unpacking the package...
|
||||
* Installing the plugin...
|
||||
* Plugin installed successfully.
|
||||
* Success: Installed 1 of 1 plugins.
|
||||
*
|
||||
* # Update from a remote zip file
|
||||
* $ wp plugin install https://github.com/envato/wp-envato-market/archive/master.zip --force
|
||||
* Downloading install package from https://github.com/envato/wp-envato-market/archive/master.zip
|
||||
* Unpacking the package...
|
||||
* Installing the plugin...
|
||||
* Renamed Github-based project from 'wp-envato-market-master' to 'wp-envato-market'.
|
||||
* Plugin updated successfully
|
||||
* Success: Installed 1 of 1 plugins.
|
||||
*
|
||||
* # Forcefully re-install all installed plugins
|
||||
* $ wp plugin install $(wp plugin list --field=name) --force
|
||||
* Installing Akismet (3.1.11)
|
||||
* Downloading install package from https://downloads.wordpress.org/plugin/akismet.3.1.11.zip...
|
||||
* Unpacking the package...
|
||||
* Installing the plugin...
|
||||
* Removing the old version of the plugin...
|
||||
* Plugin updated successfully
|
||||
* Success: Installed 1 of 1 plugins.
|
||||
*/
|
||||
public function install( $args, $assoc_args ) {
|
||||
|
||||
if ( ! is_dir( WP_PLUGIN_DIR ) ) {
|
||||
wp_mkdir_p( WP_PLUGIN_DIR );
|
||||
}
|
||||
|
||||
parent::install( $args, $assoc_args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get details about an installed plugin.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <plugin>
|
||||
* : The plugin to get.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Instead of returning the whole plugin, returns the value of a single field.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Limit the output to specific fields. Defaults to all fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Render output in a particular format.
|
||||
* ---
|
||||
* default: table
|
||||
* options:
|
||||
* - table
|
||||
* - csv
|
||||
* - json
|
||||
* - yaml
|
||||
* ---
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* $ wp plugin get bbpress --format=json
|
||||
* {"name":"bbpress","title":"bbPress","author":"The bbPress Contributors","version":"2.6-alpha","description":"bbPress is forum software with a twist from the creators of WordPress.","status":"active"}
|
||||
*/
|
||||
public function get( $args, $assoc_args ) {
|
||||
$plugin = $this->fetcher->get_check( $args[0] );
|
||||
$file = $plugin->file;
|
||||
|
||||
$plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $file, false, false );
|
||||
|
||||
$plugin_obj = (object)array(
|
||||
'name' => Utils\get_plugin_name( $file ),
|
||||
'title' => $plugin_data['Name'],
|
||||
'author' => $plugin_data['Author'],
|
||||
'version' => $plugin_data['Version'],
|
||||
'description' => wordwrap( $plugin_data['Description'] ),
|
||||
'status' => $this->get_status( $file ),
|
||||
);
|
||||
|
||||
if ( empty( $assoc_args['fields'] ) ) {
|
||||
$plugin_array = get_object_vars( $plugin_obj );
|
||||
$assoc_args['fields'] = array_keys( $plugin_array );
|
||||
}
|
||||
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
$formatter->display_item( $plugin_obj );
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall a plugin.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <plugin>...
|
||||
* : One or more plugins to uninstall.
|
||||
*
|
||||
* [--deactivate]
|
||||
* : Deactivate the plugin before uninstalling. Default behavior is to warn and skip if the plugin is active.
|
||||
*
|
||||
* [--skip-delete]
|
||||
* : If set, the plugin files will not be deleted. Only the uninstall procedure
|
||||
* will be run.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* $ wp plugin uninstall hello
|
||||
* Uninstalled and deleted 'hello' plugin.
|
||||
* Success: Installed 1 of 1 plugins.
|
||||
*/
|
||||
public function uninstall( $args, $assoc_args = array() ) {
|
||||
$successes = $errors = 0;
|
||||
$plugins = $this->fetcher->get_many( $args );
|
||||
foreach ( $plugins as $plugin ) {
|
||||
if ( is_plugin_active( $plugin->file ) && ! WP_CLI\Utils\get_flag_value( $assoc_args, 'deactivate' ) ) {
|
||||
WP_CLI::warning( "The '{$plugin->name}' plugin is active." );
|
||||
$errors++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'deactivate' ) ) {
|
||||
WP_CLI::log( "Deactivating '{$plugin->name}'..." );
|
||||
$this->chained_command = true;
|
||||
$this->deactivate( array( $plugin->name ) );
|
||||
$this->chained_command = false;
|
||||
}
|
||||
|
||||
uninstall_plugin( $plugin->file );
|
||||
|
||||
if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-delete' ) && $this->_delete( $plugin ) ) {
|
||||
WP_CLI::log( "Uninstalled and deleted '$plugin->name' plugin." );
|
||||
} else {
|
||||
WP_CLI::log( "Ran uninstall procedure for '$plugin->name' plugin without deleting." );
|
||||
}
|
||||
$successes++;
|
||||
}
|
||||
if ( ! $this->chained_command ) {
|
||||
Utils\report_batch_operation_results( 'plugin', 'uninstall', count( $args ), $successes, $errors );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the plugin is installed.
|
||||
*
|
||||
* Returns exit code 0 when installed, 1 when uninstalled.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <plugin>
|
||||
* : The plugin to check.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Check whether plugin is installed; exit status 0 if installed, otherwise 1
|
||||
* $ wp plugin is-installed hello-dolly
|
||||
* $ echo $?
|
||||
* 1
|
||||
*
|
||||
* @subcommand is-installed
|
||||
*/
|
||||
public function is_installed( $args, $assoc_args = array() ) {
|
||||
if ( $this->fetcher->get( $args[0] ) ) {
|
||||
WP_CLI::halt( 0 );
|
||||
} else {
|
||||
WP_CLI::halt( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete plugin files without deactivating or uninstalling.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <plugin>...
|
||||
* : One or more plugins to delete.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Delete plugin
|
||||
* $ wp plugin delete hello
|
||||
* Deleted 'hello' plugin.
|
||||
* Success: Deleted 1 of 1 plugins.
|
||||
*
|
||||
* # Delete inactive plugins
|
||||
* $ wp plugin delete $(wp plugin list --status=inactive --field=name)
|
||||
* Deleted 'tinymce-templates' plugin.
|
||||
* Success: Deleted 1 of 1 plugins.
|
||||
*/
|
||||
public function delete( $args, $assoc_args = array() ) {
|
||||
$successes = $errors = 0;
|
||||
foreach ( $this->fetcher->get_many( $args ) as $plugin ) {
|
||||
if ( $this->_delete( $plugin ) ) {
|
||||
WP_CLI::log( "Deleted '{$plugin->name}' plugin." );
|
||||
$successes++;
|
||||
} else {
|
||||
$errors++;
|
||||
}
|
||||
}
|
||||
if ( ! $this->chained_command ) {
|
||||
Utils\report_batch_operation_results( 'plugin', 'delete', count( $args ), $successes, $errors );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of plugins.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : Filter results based on the value of a field.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Prints the value of a single field for each plugin.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Limit the output to specific object fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Render output in a particular format.
|
||||
* ---
|
||||
* default: table
|
||||
* options:
|
||||
* - table
|
||||
* - csv
|
||||
* - count
|
||||
* - json
|
||||
* - yaml
|
||||
* ---
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields will be displayed by default for each plugin:
|
||||
*
|
||||
* * name
|
||||
* * status
|
||||
* * update
|
||||
* * version
|
||||
*
|
||||
* These fields are optionally available:
|
||||
*
|
||||
* * update_version
|
||||
* * update_package
|
||||
* * update_id
|
||||
* * title
|
||||
* * description
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # List active plugins on the site.
|
||||
* $ wp plugin list --status=active --format=json
|
||||
* [{"name":"dynamic-hostname","status":"active","update":"none","version":"0.4.2"},{"name":"tinymce-templates","status":"active","update":"none","version":"4.4.3"},{"name":"wp-multibyte-patch","status":"active","update":"none","version":"2.4"},{"name":"wp-total-hacks","status":"active","update":"none","version":"2.0.1"}]
|
||||
*
|
||||
* # List plugins on each site in a network.
|
||||
* $ wp site list --field=url | xargs -I % wp plugin list --url=%
|
||||
* +---------+----------------+--------+---------+
|
||||
* | name | status | update | version |
|
||||
* +---------+----------------+--------+---------+
|
||||
* | akismet | active-network | none | 3.1.11 |
|
||||
* | hello | inactive | none | 1.6 |
|
||||
* +---------+----------------+--------+---------+
|
||||
* +---------+----------------+--------+---------+
|
||||
* | name | status | update | version |
|
||||
* +---------+----------------+--------+---------+
|
||||
* | akismet | active-network | none | 3.1.11 |
|
||||
* | hello | inactive | none | 1.6 |
|
||||
* +---------+----------------+--------+---------+
|
||||
*
|
||||
* @subcommand list
|
||||
*/
|
||||
public function list_( $_, $assoc_args ) {
|
||||
parent::_list( $_, $assoc_args );
|
||||
}
|
||||
|
||||
/* PRIVATES */
|
||||
|
||||
private function check_active( $file, $network_wide ) {
|
||||
$required = $network_wide ? 'active-network' : 'active';
|
||||
|
||||
return $required == $this->get_status( $file );
|
||||
}
|
||||
|
||||
private function active_output( $name, $file, $network_wide, $action ) {
|
||||
$network_wide = $network_wide || ( is_multisite() && is_network_only_plugin( $file ) );
|
||||
|
||||
$check = $this->check_active( $file, $network_wide );
|
||||
|
||||
if ( ( $action == "activate" ) ? $check : ! $check ) {
|
||||
if ( $network_wide )
|
||||
WP_CLI::log( "Plugin '{$name}' network {$action}d." );
|
||||
else
|
||||
WP_CLI::log( "Plugin '{$name}' {$action}d." );
|
||||
} else {
|
||||
WP_CLI::warning( "Could not {$action} the '{$name}' plugin." );
|
||||
}
|
||||
}
|
||||
|
||||
protected function get_status( $file ) {
|
||||
if ( is_plugin_active_for_network( $file ) )
|
||||
return 'active-network';
|
||||
|
||||
if ( is_plugin_active( $file ) )
|
||||
return 'active';
|
||||
|
||||
return 'inactive';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the details of a plugin.
|
||||
*
|
||||
* @param object
|
||||
* @return array
|
||||
*/
|
||||
private function get_details( $file ) {
|
||||
$plugin_folder = get_plugins( '/' . plugin_basename( dirname( $file ) ) );
|
||||
$plugin_file = Utils\basename( $file );
|
||||
|
||||
return $plugin_folder[$plugin_file];
|
||||
}
|
||||
|
||||
private function _delete( $plugin ) {
|
||||
$plugin_dir = dirname( $plugin->file );
|
||||
if ( '.' == $plugin_dir )
|
||||
$plugin_dir = $plugin->file;
|
||||
|
||||
$path = path_join( WP_PLUGIN_DIR, $plugin_dir );
|
||||
|
||||
if ( \WP_CLI\Utils\is_windows() ) {
|
||||
// Handles plugins that are not in own folders
|
||||
// e.g. Hello Dolly -> plugins/hello.php
|
||||
if ( is_file( $path ) ) {
|
||||
$command = 'del /f /q ';
|
||||
} else {
|
||||
$command = 'rd /s /q ';
|
||||
}
|
||||
$path = str_replace( "/", "\\", $path );
|
||||
} else {
|
||||
$command = 'rm -rf ';
|
||||
}
|
||||
|
||||
return ! WP_CLI::launch( $command . $path );
|
||||
}
|
||||
}
|
||||
|
||||
WP_CLI::add_command( 'plugin', 'Plugin_Command' );
|
|
@ -1,202 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Manage theme mods.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Set the 'background_color' theme mod to '000000'.
|
||||
* $ wp theme mod set background_color 000000
|
||||
* Success: Theme mod background_color set to 000000
|
||||
*
|
||||
* # Get single theme mod in JSON format.
|
||||
* $ wp theme mod get background_color --format=json
|
||||
* [{"key":"background_color","value":"dd3333"}]
|
||||
*
|
||||
* # Remove all theme mods.
|
||||
* $ wp theme mod remove --all
|
||||
* Success: Theme mods removed.
|
||||
*/
|
||||
class Theme_Mod_command extends WP_CLI_Command {
|
||||
|
||||
private $fields = array(
|
||||
'key',
|
||||
'value'
|
||||
);
|
||||
|
||||
/**
|
||||
* Get one or more theme mods.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [<mod>...]
|
||||
* : One or more mods to get.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Returns the value of a single field.
|
||||
*
|
||||
* [--all]
|
||||
* : List all theme mods
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Render output in a particular format.
|
||||
* ---
|
||||
* default: table
|
||||
* options:
|
||||
* - table
|
||||
* - json
|
||||
* - csv
|
||||
* - yaml
|
||||
* ---
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Get all theme mods.
|
||||
* $ wp theme mod get --all
|
||||
* +------------------+---------+
|
||||
* | key | value |
|
||||
* +------------------+---------+
|
||||
* | background_color | dd3333 |
|
||||
* | link_color | #dd9933 |
|
||||
* | main_text_color | #8224e3 |
|
||||
* +------------------+---------+
|
||||
*
|
||||
* # Get single theme mod in JSON format.
|
||||
* $ wp theme mod get background_color --format=json
|
||||
* [{"key":"background_color","value":"dd3333"}]
|
||||
*
|
||||
* # Get value of a single theme mod.
|
||||
* $ wp theme mod get background_color --field=value
|
||||
* dd3333
|
||||
*
|
||||
* # Get multiple theme mods.
|
||||
* $ wp theme mod get background_color header_textcolor
|
||||
* +------------------+--------+
|
||||
* | key | value |
|
||||
* +------------------+--------+
|
||||
* | background_color | dd3333 |
|
||||
* | header_textcolor | |
|
||||
* +------------------+--------+
|
||||
*/
|
||||
public function get( $args = array(), $assoc_args = array() ) {
|
||||
|
||||
if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) {
|
||||
WP_CLI::error( "You must specify at least one mod or use --all." );
|
||||
}
|
||||
|
||||
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) {
|
||||
$args = array();
|
||||
}
|
||||
|
||||
$list = array();
|
||||
$mods = get_theme_mods();
|
||||
if ( ! is_array( $mods ) ) {
|
||||
// if no mods are set (perhaps new theme), make sure foreach still works
|
||||
$mods = array();
|
||||
}
|
||||
foreach ( $mods as $k => $v ) {
|
||||
// if mods were given, skip the others
|
||||
if ( ! empty( $args ) && ! in_array( $k, $args ) ) continue;
|
||||
|
||||
if ( is_array( $v ) ) {
|
||||
$list[] = array( 'key' => $k, 'value' => '=>' );
|
||||
foreach ( $v as $_k => $_v ) {
|
||||
$list[] = array( 'key' => " $_k", 'value' => $_v );
|
||||
}
|
||||
} else {
|
||||
$list[] = array( 'key' => $k, 'value' => $v );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// For unset mods, show blank value
|
||||
foreach ( $args as $mod ) {
|
||||
if ( ! isset( $mods[ $mod ] ) ) {
|
||||
$list[] = array( 'key' => $mod, 'value' => '' );
|
||||
}
|
||||
}
|
||||
|
||||
$formatter = new \WP_CLI\Formatter( $assoc_args, $this->fields, 'thememods' );
|
||||
$formatter->display_items( $list );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove one or more theme mods.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [<mod>...]
|
||||
* : One or more mods to remove.
|
||||
*
|
||||
* [--all]
|
||||
* : Remove all theme mods.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Remove all theme mods.
|
||||
* $ wp theme mod remove --all
|
||||
* Success: Theme mods removed.
|
||||
*
|
||||
* # Remove single theme mod.
|
||||
* $ wp theme mod remove background_color
|
||||
* Success: 1 mod removed.
|
||||
*
|
||||
* # Remove multiple theme mods.
|
||||
* $ wp theme mod remove background_color header_textcolor
|
||||
* Success: 2 mods removed.
|
||||
*/
|
||||
public function remove( $args = array(), $assoc_args = array() ) {
|
||||
|
||||
if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) {
|
||||
WP_CLI::error( "You must specify at least one mod or use --all." );
|
||||
}
|
||||
|
||||
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) {
|
||||
remove_theme_mods();
|
||||
WP_CLI::success( 'Theme mods removed.' );
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $args as $mod ) {
|
||||
remove_theme_mod( $mod );
|
||||
}
|
||||
|
||||
$count = count( $args );
|
||||
$success_message = ( 1 === $count ) ? '%d mod removed.' : '%d mods removed.';
|
||||
WP_CLI::success( sprintf( $success_message, $count ) );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a theme mod.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <mod>
|
||||
* : The name of the theme mod to set or update.
|
||||
*
|
||||
* <value>
|
||||
* : The new value.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Set theme mod
|
||||
* $ wp theme mod set background_color 000000
|
||||
* Success: Theme mod background_color set to 000000
|
||||
*/
|
||||
public function set( $args = array(), $assoc_args = array() ) {
|
||||
list( $mod, $value ) = $args;
|
||||
|
||||
set_theme_mod( $mod, $value );
|
||||
|
||||
if ( $value == get_theme_mod( $mod ) ) {
|
||||
WP_CLI::success( sprintf( "Theme mod %s set to %s.", $mod, $value ) );
|
||||
} else {
|
||||
WP_CLI::success( sprintf( "Could not update theme mod %s.", $mod ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WP_CLI::add_command( 'theme mod', 'Theme_Mod_Command' );
|
|
@ -1,776 +0,0 @@
|
|||
<?php
|
||||
|
||||
use WP_CLI\Utils;
|
||||
|
||||
/**
|
||||
* Manage themes.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Install the latest version of a theme from wordpress.org and activate
|
||||
* $ wp theme install twentysixteen --activate
|
||||
* Installing Twenty Sixteen (1.2)
|
||||
* Downloading install package from http://downloads.wordpress.org/theme/twentysixteen.1.2.zip...
|
||||
* Unpacking the package...
|
||||
* Installing the theme...
|
||||
* Theme installed successfully.
|
||||
* Activating 'twentysixteen'...
|
||||
* Success: Switched to 'Twenty Sixteen' theme.
|
||||
*
|
||||
* # Get details of an installed theme
|
||||
* $ wp theme get twentysixteen --fields=name,title,version
|
||||
* +---------+----------------+
|
||||
* | Field | Value |
|
||||
* +---------+----------------+
|
||||
* | name | Twenty Sixteen |
|
||||
* | title | Twenty Sixteen |
|
||||
* | version | 1.2 |
|
||||
* +---------+----------------+
|
||||
*
|
||||
* # Get status of theme
|
||||
* $ wp theme status twentysixteen
|
||||
* Theme twentysixteen details:
|
||||
* Name: Twenty Sixteen
|
||||
* Status: Active
|
||||
* Version: 1.2
|
||||
* Author: the WordPress team
|
||||
*
|
||||
* @package wp-cli
|
||||
*/
|
||||
class Theme_Command extends \WP_CLI\CommandWithUpgrade {
|
||||
|
||||
protected $item_type = 'theme';
|
||||
protected $upgrade_refresh = 'wp_update_themes';
|
||||
protected $upgrade_transient = 'update_themes';
|
||||
|
||||
protected $obj_fields = array(
|
||||
'name',
|
||||
'status',
|
||||
'update',
|
||||
'version'
|
||||
);
|
||||
|
||||
function __construct() {
|
||||
if ( is_multisite() ) {
|
||||
$this->obj_fields[] = 'enabled';
|
||||
}
|
||||
parent::__construct();
|
||||
|
||||
$this->fetcher = new \WP_CLI\Fetchers\Theme;
|
||||
}
|
||||
|
||||
protected function get_upgrader_class( $force ) {
|
||||
return $force ? '\\WP_CLI\\DestructiveThemeUpgrader' : 'Theme_Upgrader';
|
||||
}
|
||||
|
||||
/**
|
||||
* See the status of one or all themes.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [<theme>]
|
||||
* : A particular theme to show the status for.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* $ wp theme status twentysixteen
|
||||
* Theme twentysixteen details:
|
||||
* Name: Twenty Sixteen
|
||||
* Status: Inactive
|
||||
* Version: 1.2
|
||||
* Author: the WordPress team
|
||||
*/
|
||||
public function status( $args ) {
|
||||
if ( isset( $args[0] ) ) {
|
||||
$theme = $this->fetcher->get_check( $args[0] );
|
||||
$errors = $theme->errors();
|
||||
if ( is_wp_error( $errors ) ) {
|
||||
$message = $errors->get_error_message();
|
||||
WP_CLI::error( $message );
|
||||
}
|
||||
}
|
||||
|
||||
parent::status( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the WordPress.org theme directory.
|
||||
*
|
||||
* Displays themes in the WordPress.org theme directory matching a given
|
||||
* search query.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <search>
|
||||
* : The string to search for.
|
||||
*
|
||||
* [--per-page=<per-page>]
|
||||
* : Optional number of results to display. Defaults to 10.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Prints the value of a single field for each theme.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Ask for specific fields from the API. Defaults to name,slug,author,rating. Acceptable values:
|
||||
*
|
||||
* **name**: Theme Name
|
||||
* **slug**: Theme Slug
|
||||
* **version**: Current Version Number
|
||||
* **author**: Theme Author
|
||||
* **preview_url**: Theme Preview URL
|
||||
* **screenshot_url**: Theme Screenshot URL
|
||||
* **rating**: Theme Rating
|
||||
* **num_ratings**: Number of Theme Ratings
|
||||
* **homepage**: Theme Author's Homepage
|
||||
* **description**: Theme Description
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Render output in a particular format.
|
||||
* ---
|
||||
* default: table
|
||||
* options:
|
||||
* - table
|
||||
* - csv
|
||||
* - json
|
||||
* - count
|
||||
* - yaml
|
||||
* ---
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* $ wp theme search photo --per-page=6
|
||||
* Success: Showing 6 of 203 themes.
|
||||
* +----------------------+----------------------+--------+
|
||||
* | name | slug | rating |
|
||||
* +----------------------+----------------------+--------+
|
||||
* | Photos | photos | 100 |
|
||||
* | Infinite Photography | infinite-photography | 100 |
|
||||
* | PhotoBook | photobook | 100 |
|
||||
* | BG Photo Frame | bg-photo-frame | 0 |
|
||||
* | fPhotography | fphotography | 0 |
|
||||
* | Photo Perfect | photo-perfect | 98 |
|
||||
* +----------------------+----------------------+--------+
|
||||
*/
|
||||
public function search( $args, $assoc_args ) {
|
||||
parent::_search( $args, $assoc_args );
|
||||
}
|
||||
|
||||
protected function status_single( $args ) {
|
||||
$theme = $this->fetcher->get_check( $args[0] );
|
||||
|
||||
$status = $this->format_status( $this->get_status( $theme ), 'long' );
|
||||
|
||||
$version = $theme->get('Version');
|
||||
if ( $this->has_update( $theme->get_stylesheet() ) )
|
||||
$version .= ' (%gUpdate available%n)';
|
||||
|
||||
echo WP_CLI::colorize( \WP_CLI\Utils\mustache_render( 'theme-status.mustache', array(
|
||||
'slug' => $theme->get_stylesheet(),
|
||||
'status' => $status,
|
||||
'version' => $version,
|
||||
'name' => $theme->get('Name'),
|
||||
'author' => $theme->get('Author'),
|
||||
) ) );
|
||||
}
|
||||
|
||||
protected function get_all_items() {
|
||||
return $this->get_item_list();
|
||||
}
|
||||
|
||||
protected function get_status( $theme ) {
|
||||
if ( $this->is_active_theme( $theme ) ) {
|
||||
return 'active';
|
||||
} else if ( $theme->get_stylesheet_directory() === get_template_directory() ) {
|
||||
return 'parent';
|
||||
} else {
|
||||
return 'inactive';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate a theme.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <theme>
|
||||
* : The theme to activate.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* $ wp theme activate twentysixteen
|
||||
* Success: Switched to 'Twenty Sixteen' theme.
|
||||
*/
|
||||
public function activate( $args = array() ) {
|
||||
$theme = $this->fetcher->get_check( $args[0] );
|
||||
|
||||
$errors = $theme->errors();
|
||||
if ( is_wp_error( $errors ) ) {
|
||||
$message = $errors->get_error_message();
|
||||
WP_CLI::error( $message );
|
||||
}
|
||||
|
||||
$name = $theme->get('Name');
|
||||
|
||||
if ( 'active' === $this->get_status( $theme ) ) {
|
||||
WP_CLI::warning( "The '$name' theme is already active." );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $theme->get_stylesheet() != $theme->get_template() && ! $this->fetcher->get( $theme->get_template() ) ) {
|
||||
WP_CLI::error( "The '{$theme->get_stylesheet()}' theme cannot be activated without its parent, '{$theme->get_template()}'." );
|
||||
}
|
||||
|
||||
switch_theme( $theme->get_template(), $theme->get_stylesheet() );
|
||||
|
||||
if ( $this->is_active_theme( $theme ) ) {
|
||||
WP_CLI::success( "Switched to '$name' theme." );
|
||||
} else {
|
||||
WP_CLI::error( "Could not switch to '$name' theme." );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a theme on a WordPress multisite install.
|
||||
*
|
||||
* Permits theme to be activated from the dashboard of a site on a WordPress
|
||||
* multisite install.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <theme>
|
||||
* : The theme to enable.
|
||||
*
|
||||
* [--network]
|
||||
* : If set, the theme is enabled for the entire network
|
||||
*
|
||||
* [--activate]
|
||||
* : If set, the theme is activated for the current site. Note that
|
||||
* the "network" flag has no influence on this.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Enable theme
|
||||
* $ wp theme enable twentysixteen
|
||||
* Success: Enabled the 'Twenty Sixteen' theme.
|
||||
*
|
||||
* # Network enable theme
|
||||
* $ wp theme enable twentysixteen --network
|
||||
* Success: Network enabled the 'Twenty Sixteen' theme.
|
||||
*
|
||||
* # Network enable and activate theme for current site
|
||||
* $ wp theme enable twentysixteen --activate
|
||||
* Success: Enabled the 'Twenty Sixteen' theme.
|
||||
* Success: Switched to 'Twenty Sixteen' theme.
|
||||
*/
|
||||
public function enable( $args, $assoc_args ) {
|
||||
if ( ! is_multisite() ) {
|
||||
WP_CLI::error( 'This is not a multisite install.' );
|
||||
}
|
||||
|
||||
$theme = $this->fetcher->get_check( $args[0] );
|
||||
$name = $theme->get( 'Name' );
|
||||
|
||||
# If the --network flag is set, we'll be calling the (get|update)_site_option functions
|
||||
$_site = ! empty( $assoc_args['network'] ) ? '_site' : '';
|
||||
|
||||
# Add the current theme to the allowed themes option or site option
|
||||
$allowed_themes = call_user_func( "get{$_site}_option", 'allowedthemes' );
|
||||
if ( empty( $allowed_themes ) )
|
||||
$allowed_themes = array();
|
||||
$allowed_themes[ $theme->get_stylesheet() ] = true;
|
||||
call_user_func( "update{$_site}_option", 'allowedthemes', $allowed_themes );
|
||||
|
||||
if ( ! empty( $assoc_args['network'] ) )
|
||||
WP_CLI::success( "Network enabled the '$name' theme." );
|
||||
else
|
||||
WP_CLI::success( "Enabled the '$name' theme." );
|
||||
|
||||
# If the --activate flag is set, activate the theme for the current site
|
||||
if ( ! empty( $assoc_args['activate'] ) ) {
|
||||
$this->activate( $args );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a theme on a WordPress multisite install.
|
||||
*
|
||||
* Removes ability for a theme to be activated from the dashboard of a site
|
||||
* on a WordPress multisite install.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <theme>
|
||||
* : The theme to disable.
|
||||
*
|
||||
* [--network]
|
||||
* : If set, the theme is disabled on the network level. Note that
|
||||
* individual sites may still have this theme enabled if it was
|
||||
* enabled for them independently.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Disable theme
|
||||
* $ wp theme disable twentysixteen
|
||||
* Success: Disabled the 'Twenty Sixteen' theme.
|
||||
*
|
||||
* # Disable theme in network level
|
||||
* $ wp theme disable twentysixteen --network
|
||||
* Success: Network disabled the 'Twenty Sixteen' theme.
|
||||
*/
|
||||
public function disable( $args, $assoc_args ) {
|
||||
if ( ! is_multisite() ) {
|
||||
WP_CLI::error( 'This is not a multisite install.' );
|
||||
}
|
||||
|
||||
$theme = $this->fetcher->get_check( $args[0] );
|
||||
$name = $theme->get( 'Name' );
|
||||
|
||||
# If the --network flag is set, we'll be calling the (get|update)_site_option functions
|
||||
$_site = ! empty( $assoc_args['network'] ) ? '_site' : '';
|
||||
|
||||
# Add the current theme to the allowed themes option or site option
|
||||
$allowed_themes = call_user_func( "get{$_site}_option", 'allowedthemes' );
|
||||
if ( ! empty( $allowed_themes[ $theme->get_stylesheet() ] ) )
|
||||
unset( $allowed_themes[ $theme->get_stylesheet() ] );
|
||||
call_user_func( "update{$_site}_option", 'allowedthemes', $allowed_themes );
|
||||
|
||||
if ( ! empty( $assoc_args['network'] ) )
|
||||
WP_CLI::success( "Network disabled the '$name' theme." );
|
||||
else
|
||||
WP_CLI::success( "Disabled the '$name' theme." );
|
||||
}
|
||||
|
||||
private function is_active_theme( $theme ) {
|
||||
return $theme->get_stylesheet_directory() == get_stylesheet_directory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to a theme or to the theme directory.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [<theme>]
|
||||
* : The theme to get the path to. Path includes "style.css" file.
|
||||
* If not set, will return the path to the themes directory.
|
||||
*
|
||||
* [--dir]
|
||||
* : If set, get the path to the closest parent directory, instead of the
|
||||
* theme's "style.css" file.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Get theme path
|
||||
* $ wp theme path
|
||||
* /var/www/example.com/public_html/wp-content/themes
|
||||
*
|
||||
* # Change directory to theme path
|
||||
* $ cd $(wp theme path)
|
||||
*/
|
||||
public function path( $args, $assoc_args ) {
|
||||
if ( empty( $args ) ) {
|
||||
$path = WP_CONTENT_DIR . '/themes';
|
||||
} else {
|
||||
$theme = $this->fetcher->get_check( $args[0] );
|
||||
|
||||
$path = $theme->get_stylesheet_directory();
|
||||
|
||||
if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'dir' ) )
|
||||
$path .= '/style.css';
|
||||
}
|
||||
|
||||
WP_CLI::line( $path );
|
||||
}
|
||||
|
||||
protected function install_from_repo( $slug, $assoc_args ) {
|
||||
$api = themes_api( 'theme_information', array( 'slug' => $slug ) );
|
||||
|
||||
if ( is_wp_error( $api ) ) {
|
||||
return $api;
|
||||
}
|
||||
|
||||
if ( isset( $assoc_args['version'] ) ) {
|
||||
self::alter_api_response( $api, $assoc_args['version'] );
|
||||
}
|
||||
|
||||
if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) ) {
|
||||
$theme = wp_get_theme( $slug );
|
||||
if ( $theme->exists() ) {
|
||||
// We know this will fail, so avoid a needless download of the package.
|
||||
return new WP_Error( 'already_installed', 'Theme already installed.' );
|
||||
}
|
||||
// Clear cache so WP_Theme doesn't create a "missing theme" object.
|
||||
$cache_hash = md5( $theme->theme_root . '/' . $theme->stylesheet );
|
||||
foreach( array( 'theme', 'screenshot', 'headers', 'page_templates' ) as $key ) {
|
||||
wp_cache_delete( $key . '-' . $cache_hash, 'themes' );
|
||||
}
|
||||
}
|
||||
|
||||
WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name, ENT_QUOTES ), $api->version ) );
|
||||
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'version' ) != 'dev' ) {
|
||||
WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version );
|
||||
}
|
||||
$result = $this->get_upgrader( $assoc_args )->install( $api->download_link );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function get_item_list() {
|
||||
$items = array();
|
||||
|
||||
if ( is_multisite() ) {
|
||||
$site_enabled = get_option( 'allowedthemes' );
|
||||
if ( empty( $site_enabled ) )
|
||||
$site_enabled = array();
|
||||
|
||||
$network_enabled = get_site_option( 'allowedthemes' );
|
||||
if ( empty( $network_enabled ) )
|
||||
$network_enabled = array();
|
||||
}
|
||||
|
||||
foreach ( wp_get_themes() as $key => $theme ) {
|
||||
$file = $theme->get_stylesheet_directory();
|
||||
$update_info = $this->get_update_info( $theme->get_stylesheet() );
|
||||
|
||||
$items[ $file ] = array(
|
||||
'name' => $key,
|
||||
'status' => $this->get_status( $theme ),
|
||||
'update' => (bool) $update_info,
|
||||
'update_version' => $update_info['new_version'],
|
||||
'update_package' => $update_info['package'],
|
||||
'version' => $theme->get('Version'),
|
||||
'update_id' => $theme->get_stylesheet(),
|
||||
'title' => $theme->get('Name'),
|
||||
'description' => $theme->get('Description'),
|
||||
'author' => $theme->get('Author'),
|
||||
);
|
||||
|
||||
if ( is_multisite() ) {
|
||||
if ( ! empty( $site_enabled[ $key ] ) && ! empty( $network_enabled[ $key ] ) )
|
||||
$items[ $file ]['enabled'] = 'network,site';
|
||||
elseif ( ! empty( $network_enabled[ $key ] ) )
|
||||
$items[ $file ]['enabled'] = 'network';
|
||||
elseif ( ! empty( $site_enabled[ $key ] ) )
|
||||
$items[ $file ]['enabled'] = 'site';
|
||||
else
|
||||
$items[ $file ]['enabled'] = 'no';
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
protected function filter_item_list( $items, $args ) {
|
||||
$theme_files = array();
|
||||
foreach ( $args as $arg ) {
|
||||
$theme_files[] = $this->fetcher->get_check( $arg )->get_stylesheet_directory();
|
||||
}
|
||||
|
||||
return \WP_CLI\Utils\pick_fields( $items, $theme_files );
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a theme.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <theme|zip|url>...
|
||||
* : A theme slug, the path to a local zip file, or URL to a remote zip file.
|
||||
*
|
||||
* [--version=<version>]
|
||||
* : If set, get that particular version from wordpress.org, instead of the
|
||||
* stable version.
|
||||
*
|
||||
* [--force]
|
||||
* : If set, the command will overwrite any installed version of the theme, without prompting
|
||||
* for confirmation.
|
||||
*
|
||||
* [--activate]
|
||||
* : If set, the theme will be activated immediately after install.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Install the latest version from wordpress.org and activate
|
||||
* $ wp theme install twentysixteen --activate
|
||||
* Installing Twenty Sixteen (1.2)
|
||||
* Downloading install package from http://downloads.wordpress.org/theme/twentysixteen.1.2.zip...
|
||||
* Unpacking the package...
|
||||
* Installing the theme...
|
||||
* Theme installed successfully.
|
||||
* Activating 'twentysixteen'...
|
||||
* Success: Switched to 'Twenty Sixteen' theme.
|
||||
*
|
||||
* # Install from a local zip file
|
||||
* $ wp theme install ../my-theme.zip
|
||||
*
|
||||
* # Install from a remote zip file
|
||||
* $ wp theme install http://s3.amazonaws.com/bucketname/my-theme.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef
|
||||
*/
|
||||
function install( $args, $assoc_args ) {
|
||||
|
||||
$theme_root = get_theme_root();
|
||||
if ( $theme_root && ! is_dir( $theme_root ) ) {
|
||||
wp_mkdir_p( $theme_root );
|
||||
register_theme_directory( $theme_root );
|
||||
}
|
||||
|
||||
parent::install( $args, $assoc_args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get details about a theme.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <theme>
|
||||
* : The theme to get.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Instead of returning the whole theme, returns the value of a single field.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Limit the output to specific fields. Defaults to all fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Render output in a particular format.
|
||||
* ---
|
||||
* default: table
|
||||
* options:
|
||||
* - table
|
||||
* - csv
|
||||
* - json
|
||||
* - yaml
|
||||
* ---
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* $ wp theme get twentysixteen --fields=name,title,version
|
||||
* +---------+----------------+
|
||||
* | Field | Value |
|
||||
* +---------+----------------+
|
||||
* | name | Twenty Sixteen |
|
||||
* | title | Twenty Sixteen |
|
||||
* | version | 1.2 |
|
||||
* +---------+----------------+
|
||||
*/
|
||||
public function get( $args, $assoc_args ) {
|
||||
$theme = $this->fetcher->get_check( $args[0] );
|
||||
|
||||
$errors = $theme->errors();
|
||||
if ( is_wp_error( $errors ) ) {
|
||||
$message = $errors->get_error_message();
|
||||
WP_CLI::error( $message );
|
||||
}
|
||||
|
||||
// WP_Theme object employs magic getter, unfortunately
|
||||
$theme_vars = array( 'name', 'title', 'version', 'parent_theme', 'template_dir', 'stylesheet_dir', 'template', 'stylesheet', 'screenshot', 'description', 'author', 'tags', 'theme_root', 'theme_root_uri',
|
||||
);
|
||||
$theme_obj = new stdClass;
|
||||
foreach ( $theme_vars as $var ) {
|
||||
$theme_obj->$var = $theme->$var;
|
||||
}
|
||||
|
||||
$theme_obj->description = wordwrap( $theme_obj->description );
|
||||
|
||||
if ( empty( $assoc_args['fields'] ) ) {
|
||||
$assoc_args['fields'] = $theme_vars;
|
||||
}
|
||||
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
$formatter->display_item( $theme_obj );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update one or more themes.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [<theme>...]
|
||||
* : One or more themes to update.
|
||||
*
|
||||
* [--all]
|
||||
* : If set, all themes that have updates will be updated.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Output summary as table or summary. Defaults to table.
|
||||
*
|
||||
* [--version=<version>]
|
||||
* : If set, the theme will be updated to the specified version.
|
||||
*
|
||||
* [--dry-run]
|
||||
* : Preview which themes would be updated.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Update multiple themes
|
||||
* $ wp theme update twentyfifteen twentysixteen
|
||||
* Downloading update from https://downloads.wordpress.org/theme/twentyfifteen.1.5.zip...
|
||||
* Unpacking the update...
|
||||
* Installing the latest version...
|
||||
* Removing the old version of the theme...
|
||||
* Theme updated successfully.
|
||||
* Downloading update from https://downloads.wordpress.org/theme/twentysixteen.1.2.zip...
|
||||
* Unpacking the update...
|
||||
* Installing the latest version...
|
||||
* Removing the old version of the theme...
|
||||
* Theme updated successfully.
|
||||
* +---------------+-------------+-------------+---------+
|
||||
* | name | old_version | new_version | status |
|
||||
* +---------------+-------------+-------------+---------+
|
||||
* | twentyfifteen | 1.4 | 1.5 | Updated |
|
||||
* | twentysixteen | 1.1 | 1.2 | Updated |
|
||||
* +---------------+-------------+-------------+---------+
|
||||
* Success: Updated 2 of 2 themes.
|
||||
*
|
||||
* # Update all themes
|
||||
* $ wp theme update --all
|
||||
*
|
||||
* @alias upgrade
|
||||
*/
|
||||
function update( $args, $assoc_args ) {
|
||||
if ( isset( $assoc_args['version'] ) ) {
|
||||
foreach ( $this->fetcher->get_many( $args ) as $theme ) {
|
||||
$r = delete_theme( $theme->stylesheet );
|
||||
if ( is_wp_error( $r ) ) {
|
||||
WP_CLI::warning( $r );
|
||||
} else {
|
||||
$assoc_args['force'] = true;
|
||||
$this->install( array( $theme->stylesheet ), $assoc_args );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
parent::update_many( $args, $assoc_args );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the theme is installed.
|
||||
*
|
||||
* Returns exit code 0 when installed, 1 when uninstalled.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <theme>
|
||||
* : The theme to check.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # Check whether theme is installed; exit status 0 if installed, otherwise 1
|
||||
* $ wp theme is-installed hello-dolly
|
||||
* $ echo $?
|
||||
* 1
|
||||
*
|
||||
* @subcommand is-installed
|
||||
*/
|
||||
public function is_installed( $args, $assoc_args = array() ) {
|
||||
$theme = wp_get_theme( $args[0] );
|
||||
|
||||
if ( $theme->exists() ) {
|
||||
WP_CLI::halt( 0 );
|
||||
} else {
|
||||
WP_CLI::halt( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a theme.
|
||||
*
|
||||
* Removes the theme from the filesystem.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <theme>...
|
||||
* : One or more themes to delete.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* $ wp theme delete twentytwelve
|
||||
* Deleted 'twentytwelve' theme.
|
||||
* Success: Deleted 1 of 1 themes.
|
||||
*
|
||||
* @alias uninstall
|
||||
*/
|
||||
public function delete( $args ) {
|
||||
$successes = $errors = 0;
|
||||
foreach ( $this->fetcher->get_many( $args ) as $theme ) {
|
||||
$theme_slug = $theme->get_stylesheet();
|
||||
|
||||
if ( $this->is_active_theme( $theme ) ) {
|
||||
WP_CLI::warning( "Can't delete the currently active theme: $theme_slug" );
|
||||
$errors++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$r = delete_theme( $theme_slug );
|
||||
|
||||
if ( is_wp_error( $r ) ) {
|
||||
WP_CLI::warning( $r );
|
||||
$errors++;
|
||||
} else {
|
||||
WP_CLI::log( "Deleted '$theme_slug' theme." );
|
||||
$successes++;
|
||||
}
|
||||
}
|
||||
if ( ! $this->chained_command ) {
|
||||
Utils\report_batch_operation_results( 'theme', 'delete', count( $args ), $successes, $errors );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of themes.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : Filter results based on the value of a field.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Prints the value of a single field for each theme.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Limit the output to specific object fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Render output in a particular format.
|
||||
* ---
|
||||
* default: table
|
||||
* options:
|
||||
* - table
|
||||
* - csv
|
||||
* - json
|
||||
* - count
|
||||
* - yaml
|
||||
* ---
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields will be displayed by default for each theme:
|
||||
*
|
||||
* * name
|
||||
* * status
|
||||
* * update
|
||||
* * version
|
||||
*
|
||||
* These fields are optionally available:
|
||||
*
|
||||
* * update_version
|
||||
* * update_package
|
||||
* * update_id
|
||||
* * title
|
||||
* * description
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* # List themes
|
||||
* $ wp theme list --status=inactive --format=csv
|
||||
* name,status,update,version
|
||||
* twentyfourteen,inactive,none,1.7
|
||||
* twentysixteen,inactive,available,1.1
|
||||
*
|
||||
* @subcommand list
|
||||
*/
|
||||
public function list_( $_, $assoc_args ) {
|
||||
parent::_list( $_, $assoc_args );
|
||||
}
|
||||
}
|
||||
|
||||
WP_CLI::add_command( 'theme', 'Theme_Command' );
|
|
@ -1,6 +0,0 @@
|
|||
Plugin %9{{slug}}%n details:
|
||||
Name: {{name}}
|
||||
Status: {{status}}%n
|
||||
Version: {{version}}
|
||||
Author: {{author}}
|
||||
Description: {{description}}
|
|
@ -1,5 +0,0 @@
|
|||
Theme %9{{slug}}%n details:
|
||||
Name: {{name}}
|
||||
Status: {{status}}%n
|
||||
Version: {{version}}
|
||||
Author: {{author}}
|
Loading…
Add table
Add a link
Reference in a new issue