From d5e861d4a0f3aee7edf8a0e89c8bdcbea48798f7 Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Mon, 13 Apr 2020 08:22:46 +0200 Subject: [PATCH 1/2] Change Travis CI config to enforce PHP 7.4 compatibility --- .travis.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index c79375631..c0ea7923d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ sudo: false dist: trusty language: php -php: 7.3 +php: 7.4 notifications: email: @@ -51,7 +51,7 @@ jobs: - composer phpcs env: BUILD=sniff - stage: test - php: 7.4snapshot + php: 7.4 env: WP_VERSION=latest - stage: test php: 7.3 @@ -78,7 +78,3 @@ jobs: php: 5.4 dist: precise env: WP_VERSION=5.1 - allow_failures: - - stage: test - php: 7.4snapshot - env: WP_VERSION=latest From ce488a6ecd4673603f193e5479744d90a5adbf8d Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Sat, 4 Jul 2020 09:08:11 +0200 Subject: [PATCH 2/2] Merge latest master --- .actrc | 3 + .github/workflows/code-quality.yml | 102 +++++++++++++++++++++++++++++ .travis.yml | 17 ++--- README.md | 23 ++++++- composer.json | 3 +- features/cron-event.feature | 31 +++++++++ features/cron.feature | 33 +++++++--- phpcs.xml.dist | 2 +- src/Cron_Event_Command.php | 66 ++++++++++++++++--- 9 files changed, 248 insertions(+), 32 deletions(-) create mode 100644 .actrc create mode 100644 .github/workflows/code-quality.yml diff --git a/.actrc b/.actrc new file mode 100644 index 000000000..99e6b7ecc --- /dev/null +++ b/.actrc @@ -0,0 +1,3 @@ +# Configuration file for nektos/act. +# See https://github.com/nektos/act#configuration +-P ubuntu-latest=shivammathur/node:latest diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml new file mode 100644 index 000000000..6f6781872 --- /dev/null +++ b/.github/workflows/code-quality.yml @@ -0,0 +1,102 @@ +name: Code Quality Checks + +on: pull_request + +jobs: + + lint: #----------------------------------------------------------------------- + name: Lint PHP files + runs-on: ubuntu-latest + steps: + - name: Check out source code + uses: actions/checkout@v2 + + - name: Check existence of composer.json file + id: check_composer_file + uses: andstor/file-existence-action@v1 + with: + files: "composer.json" + + - name: Set up PHP envirnoment + uses: shivammathur/setup-php@v2 + with: + php-version: '7.4' + tools: cs2pr + + - name: Get Composer cache Directory + if: steps.check_composer_file.outputs.files_exists == 'true' + id: composer-cache + run: | + echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Use Composer cache + if: steps.check_composer_file.outputs.files_exists == 'true' + uses: actions/cache@v1 + with: + path: ${{ steps['composer-cache'].outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Install dependencies + if: steps.check_composer_file.outputs.files_exists == 'true' + run: COMPOSER_ROOT_VERSION=dev-master composer install --prefer-dist --no-progress --no-suggest + + - name: Check existence of vendor/bin/parallel-lint file + id: check_linter_file + uses: andstor/file-existence-action@v1 + with: + files: "vendor/bin/parallel-lint" + + - name: Run Linter + if: steps.check_linter_file.outputs.files_exists == 'true' + run: vendor/bin/parallel-lint -j 10 . --exclude vendor --checkstyle | cs2pr + + phpcs: #---------------------------------------------------------------------- + name: PHPCS + runs-on: ubuntu-latest + + steps: + - name: Check out source code + uses: actions/checkout@v2 + + - name: Check existence of composer.json & phpcs.xml.dist files + id: check_files + uses: andstor/file-existence-action@v1 + with: + files: "composer.json, phpcs.xml.dist" + + - name: Set up PHP envirnoment + uses: shivammathur/setup-php@v2 + with: + php-version: '7.4' + tools: cs2pr + + - name: Get Composer cache Directory + if: steps.check_files.outputs.files_exists == 'true' + id: composer-cache + run: | + echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Use Composer cache + if: steps.check_files.outputs.files_exists == 'true' + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Install dependencies + if: steps.check_files.outputs.files_exists == 'true' + run: COMPOSER_ROOT_VERSION=dev-master composer install --prefer-dist --no-progress --no-suggest + + - name: Check existence of vendor/bin/phpcs file + id: check_phpcs_binary_file + uses: andstor/file-existence-action@v1 + with: + files: "vendor/bin/phpcs" + + - name: Run PHPCS + if: steps.check_phpcs_binary_file.outputs.files_exists == 'true' + run: vendor/bin/phpcs -q --report=checkstyle | cs2pr diff --git a/.travis.yml b/.travis.yml index c0ea7923d..9d91a661f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,12 @@ -sudo: false -dist: trusty +os: linux +dist: xenial language: php php: 7.4 +services: + - mysql + notifications: email: on_success: never @@ -45,11 +48,6 @@ script: jobs: include: - - stage: sniff - script: - - composer lint - - composer phpcs - env: BUILD=sniff - stage: test php: 7.4 env: WP_VERSION=latest @@ -71,10 +69,7 @@ jobs: - stage: test php: 5.6 env: WP_VERSION=3.7.11 + dist: trusty - stage: test php: 5.6 env: WP_VERSION=trunk - - stage: test - php: 5.4 - dist: precise - env: WP_VERSION=5.1 diff --git a/README.md b/README.md index 2e83df4ba..bf560792d 100644 --- a/README.md +++ b/README.md @@ -311,6 +311,27 @@ There are no additional fields. $ wp cron schedule list --fields=name --format=ids hourly twicedaily daily + + +### wp cron event unschedule + +Unschedules all cron events for a given hook. + +~~~ +wp cron event unschedule +~~~ + +**OPTIONS** + + + Name of the hook for which all events should be unscheduled. + +**EXAMPLES** + + # Unschedule a cron event on given hook. + $ wp cron event unschedule cron_test + Success: Unscheduled 2 events with hook 'cron_test'. + ## Installing This package is included with WP-CLI itself, no additional installation necessary. @@ -343,7 +364,7 @@ Once you've decided to commit the time to seeing your pull request through, [ple ## Support -Github issues aren't for general support questions, but there are other venues you can try: https://wp-cli.org/#support +GitHub issues aren't for general support questions, but there are other venues you can try: https://wp-cli.org/#support *This README.md is generated dynamically from the project's codebase using `wp scaffold package-readme` ([doc](https://github.com/wp-cli/scaffold-package-command#wp-scaffold-package-readme)). To suggest changes, please submit a pull request against the corresponding part of the codebase.* diff --git a/composer.json b/composer.json index fd2519c7c..40ab7a31e 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,8 @@ "cron event run", "cron event schedule", "cron schedule", - "cron schedule list" + "cron schedule list", + "cron event unschedule" ] }, "autoload": { diff --git a/features/cron-event.feature b/features/cron-event.feature index 38697bbff..45f9a66cc 100644 --- a/features/cron-event.feature +++ b/features/cron-event.feature @@ -37,3 +37,34 @@ Feature: Manage WP Cron events """ Executed a total of 1 cron event """ + + @require-wp-4.9.0 + Scenario: Unschedule cron event + When I run `wp cron event schedule wp_cli_test_event_1 now hourly` + And I try `wp cron event unschedule wp_cli_test_event_1` + Then STDOUT should contain: + """ + Success: Unscheduled 1 event for hook 'wp_cli_test_event_1'. + """ + + When I run `wp cron event schedule wp_cli_test_event_2 now hourly` + And I run `wp cron event schedule wp_cli_test_event_2 '+1 hour' hourly` + And I try `wp cron event unschedule wp_cli_test_event_2` + Then STDOUT should contain: + """ + Success: Unscheduled 2 events for hook 'wp_cli_test_event_2'. + """ + + When I try `wp cron event unschedule wp_cli_test_event` + Then STDERR should be: + """ + Error: No events found for hook 'wp_cli_test_event'. + """ + + @less-than-wp-4.9.0 + Scenario: Unschedule cron event for WP < 4.9.0, wp_unschedule_hook was not included + When I try `wp cron event unschedule wp_cli_test_event_1` + Then STDERR should be: + """ + Error: Unscheduling events is only supported from WordPress 4.9.0 onwards. + """ diff --git a/features/cron.feature b/features/cron.feature index b6d8630a6..79d4985c6 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -5,7 +5,7 @@ Feature: Manage WP-Cron events and schedules And I run `wp config set DISABLE_WP_CRON false --raw --type=constant --anchor='// ** MySQL settings - You can get this info from your web host ** //'` Scenario: Scheduling and then deleting an event - When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour 5 minutes' --apple=banana` + When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour 5 minutes' --0=banana` Then STDOUT should contain: """ Success: Scheduled event with hook 'wp_cli_test_event_1' @@ -13,8 +13,8 @@ Feature: Manage WP-Cron events and schedules When I run `wp cron event list --format=csv --fields=hook,recurrence,args` Then STDOUT should be CSV containing: - | hook | recurrence | args | - | wp_cli_test_event_1 | Non-repeating | {"apple":"banana"} | + | hook | recurrence | args | + | wp_cli_test_event_1 | Non-repeating | ["banana"] | When I run `wp cron event list --fields=hook,next_run_relative | grep wp_cli_test_event_1` Then STDOUT should contain: @@ -74,15 +74,15 @@ Feature: Manage WP-Cron events and schedules """ Scenario: Scheduling, running, and deleting duplicate events - When I run `wp cron event schedule wp_cli_test_event_5 '+20 minutes' --apple=banana` - When I run `wp cron event schedule wp_cli_test_event_5 '+20 minutes' --foo=bar` + When I run `wp cron event schedule wp_cli_test_event_5 '+20 minutes' --0=banana` + When I run `wp cron event schedule wp_cli_test_event_5 '+20 minutes' --0=bar` Then STDOUT should not be empty When I run `wp cron event list --format=csv --fields=hook,recurrence,args` Then STDOUT should be CSV containing: - | hook | recurrence | args | - | wp_cli_test_event_5 | Non-repeating | {"apple":"banana"} | - | wp_cli_test_event_5 | Non-repeating | {"foo":"bar"} | + | hook | recurrence | args | + | wp_cli_test_event_5 | Non-repeating | ["banana"] | + | wp_cli_test_event_5 | Non-repeating | ["bar"] | When I run `wp cron event run wp_cli_test_event_5` Then STDOUT should contain: @@ -110,8 +110,8 @@ Feature: Manage WP-Cron events and schedules Error: Invalid cron event 'wp_cli_test_event_5' """ - When I run `wp cron event schedule wp_cli_test_event_5 '+20 minutes' --apple=banana` - When I run `wp cron event schedule wp_cli_test_event_5 '+20 minutes' --foo=bar` + When I run `wp cron event schedule wp_cli_test_event_5 '+20 minutes' --0=banana` + When I run `wp cron event schedule wp_cli_test_event_5 '+20 minutes' --0=bar` Then STDOUT should not be empty When I run `wp cron event list` @@ -318,3 +318,16 @@ Feature: Manage WP-Cron events and schedules """ wp_cli_test_event_1 wp_cli_test_event_1 """ + + Scenario: Scheduling an event with non-numerically indexed arguments + When I try `wp cron event schedule wp_cli_test_args_event '+10 minutes' --foo=banana --bar=apple` + Then STDOUT should not be empty + And STDERR should be: + """ + Warning: Numeric keys should be used for the hook arguments. + """ + + When I run `wp cron event list --format=csv --fields=hook,recurrence,args` + Then STDOUT should be CSV containing: + | hook | recurrence | args | + | wp_cli_test_args_event | Non-repeating | {"foo":"banana","bar":"apple"} | diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 4c5ea7966..4c6c041c9 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -38,7 +38,7 @@ - + diff --git a/src/Cron_Event_Command.php b/src/Cron_Event_Command.php index 30d4b06a5..ee052c13c 100644 --- a/src/Cron_Event_Command.php +++ b/src/Cron_Event_Command.php @@ -138,7 +138,7 @@ public function list_( $args, $assoc_args ) { * : How often the event should recur. See `wp cron schedule list` for available schedule names. Defaults to no recurrence. * * [--=] - * : Associative args for the event. + * : Arguments to pass to the hook for the event. should be a numeric key, not a string. * * ## EXAMPLES * @@ -150,11 +150,14 @@ public function list_( $args, $assoc_args ) { * $ wp cron event schedule cron_test now hourly * Success: Scheduled event with hook 'cron_test' for 2016-05-31 10:20:32 GMT. * - * # Schedule new cron event and pass associative arguments - * $ wp cron event schedule cron_test '+1 hour' --foo=1 --bar=2 + * # Schedule new cron event and pass arguments + * $ wp cron event schedule cron_test '+1 hour' --0=first-argument --1=second-argument * Success: Scheduled event with hook 'cron_test' for 2016-05-31 11:21:35 GMT. */ public function schedule( $args, $assoc_args ) { + if ( count( $assoc_args ) && count( array_filter( array_keys( $assoc_args ), 'is_string' ) ) ) { + WP_CLI::warning( 'Numeric keys should be used for the hook arguments.' ); + } $hook = $args[0]; $next_run = Utils\get_flag_value( $args, 1, 'now' ); @@ -269,6 +272,53 @@ public function run( $args, $assoc_args ) { WP_CLI::success( sprintf( $message, $executed ) ); } + /** + * Unschedules all cron events for a given hook. + * + * ## OPTIONS + * + * + * : Name of the hook for which all events should be unscheduled. + * + * ## EXAMPLES + * + * # Unschedule a cron event on given hook. + * $ wp cron event unschedule cron_test + * Success: Unscheduled 2 events with hook 'cron_test'. + */ + public function unschedule( $args, $assoc_args ) { + + list( $hook ) = $args; + + if ( Utils\wp_version_compare( '4.9.0', '<' ) ) { + WP_CLI::error( 'Unscheduling events is only supported from WordPress 4.9.0 onwards.' ); + } + + $unscheduled = wp_unschedule_hook( $hook ); + + if ( empty( $unscheduled ) ) { + $message = 'Failed to unschedule events for hook \'%1\$s.'; + + // If 0 event found on hook. + if ( 0 === $unscheduled ) { + $message = "No events found for hook '%1\$s'."; + } + + WP_CLI::error( sprintf( $message, $hook ) ); + + } else { + WP_CLI::success( + sprintf( + 'Unscheduled %1$d %2$s for hook \'%3$s\'.', + $unscheduled, + Utils\pluralize( 'event', $unscheduled ), + $hook + ) + ); + } + + } + /** * Executes an event immediately. * @@ -428,7 +478,7 @@ private static function interval( $since ) { $since = absint( $since ); - // array of time period chunks + // Array of time period chunks. $chunks = array( array( 60 * 60 * 24 * 365, 'year' ), array( 60 * 60 * 24 * 30, 'month' ), @@ -449,24 +499,24 @@ private static function interval( $since ) { $seconds = $chunks[ $i ][0]; $name = $chunks[ $i ][1]; - // finding the biggest chunk (if the chunk fits, break) + // Finding the biggest chunk (if the chunk fits, break). $count = floor( $since / $seconds ); if ( floatval( 0 ) !== $count ) { break; } } - // set output var + // Set output var. $output = sprintf( '%d %s', $count, Utils\pluralize( $name, absint( $count ) ) ); - // step two: the second chunk + // Step two: the second chunk. if ( $i + 1 < $j ) { $seconds2 = $chunks[ $i + 1 ][0]; $name2 = $chunks[ $i + 1 ][1]; $count2 = floor( ( $since - ( $seconds * $count ) ) / $seconds2 ); if ( floatval( 0 ) !== $count2 ) { - // add to output var + // Add to output var. $output .= ' ' . sprintf( '%d %s', $count2, Utils\pluralize( $name2, absint( $count2 ) ) ); } }