Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WP-CLI #1071

Merged
merged 73 commits into from
Dec 2, 2024
Merged

WP-CLI #1071

Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
163dd7a
add files
crstauf Jun 19, 2024
a34d670
eliminate code smells
crstauf Jun 19, 2024
3e3246f
add logs command
crstauf Jun 21, 2024
76e55cf
Merge branch 'trunk' into wpcli
crstauf Jun 21, 2024
b947a6e
add unique and priority parameters
crstauf Jul 3, 2024
d824cbc
use accurate variable names and language
crstauf Jul 3, 2024
d3e9106
improve fail detection and improve unscheduling of multiple actions
crstauf Jul 3, 2024
bfbea08
redundancy to ensure in wp cli environment
crstauf Jul 3, 2024
9da1887
catch deletion failures
crstauf Jul 6, 2024
2e6aec6
catch action retrieval errors
crstauf Jul 6, 2024
9b6ac43
catch exception when creating action
crstauf Jul 6, 2024
22654ee
must allow empty function parameters
crstauf Jul 6, 2024
1544e27
cleanup creation success
crstauf Jul 6, 2024
23dc21e
permit empty function parameters
crstauf Jul 6, 2024
645c858
cleanup
crstauf Jul 6, 2024
1565b5e
improve display of action log entries
crstauf Jul 8, 2024
b56f255
fix version sorting
crstauf Jul 18, 2024
830738f
fix 'claimed' parameter
crstauf Jul 18, 2024
673c2b7
explicitly define return format and add to debug info
crstauf Jul 18, 2024
46eb6cb
improve debug info
crstauf Jul 18, 2024
633a800
cleanup the next command
crstauf Jul 18, 2024
a2c5313
replace comma with semicolon
crstauf Jul 29, 2024
bcce836
save
crstauf Jul 29, 2024
123f8f1
save
crstauf Jul 30, 2024
815bf15
add help text
crstauf Jul 30, 2024
2626948
improve translatability
crstauf Jul 31, 2024
44bb388
remove @uses phpdoc statements
crstauf Jul 31, 2024
29872c7
remove parameter restriction
crstauf Jul 31, 2024
3c2e1ce
declare property
crstauf Jul 31, 2024
8a4cd8b
improve command description
crstauf Aug 1, 2024
e2cde16
add active column to versions table
crstauf Aug 1, 2024
ee3d64e
call function directly
crstauf Aug 1, 2024
45b4038
improve parameter description
crstauf Aug 1, 2024
9fab4dc
add check for fields parameter set to log_entries
crstauf Aug 1, 2024
f3fad9a
fix variable name
crstauf Aug 1, 2024
e7659a1
change method to retrieve class name
crstauf Aug 1, 2024
eaa3bfc
remove unused function
crstauf Aug 1, 2024
04c4527
update link
crstauf Aug 1, 2024
3f136e2
eliminate smelly code
crstauf Aug 1, 2024
5c8c14c
remove trailing comma
crstauf Aug 1, 2024
d88bc18
add list of commands to documentation
crstauf Aug 1, 2024
e3e0332
eliminate code smells
crstauf Aug 1, 2024
0cda6c1
change function names
crstauf Aug 1, 2024
53a608f
escape translation output
crstauf Aug 1, 2024
5971a6b
add todo
crstauf Aug 3, 2024
891116a
save
crstauf Aug 5, 2024
ee7c12b
Merge branch 'trunk' into wpcli
crstauf Aug 12, 2024
fc44be7
namespace
crstauf Aug 14, 2024
60c66ff
rename files
crstauf Aug 14, 2024
28ce0cb
save
crstauf Aug 14, 2024
fcca8ab
save
crstauf Aug 14, 2024
f60e586
save
crstauf Aug 14, 2024
001ac6a
save
crstauf Aug 14, 2024
e5b492e
save
crstauf Aug 14, 2024
4832673
Merge branch 'master' into wpcli
crstauf Aug 15, 2024
4a300e8
Merge branch 'trunk' into wpcli
crstauf Aug 21, 2024
375ecd3
Merge branch 'trunk' into wpcli
crstauf Aug 26, 2024
030e3f1
Merge branch 'trunk' into wpcli
crstauf Sep 5, 2024
b2763c4
Merge branch 'trunk' into wpcli
crstauf Sep 14, 2024
ccfa148
Merge branch 'trunk' into wpcli
crstauf Sep 18, 2024
e6efe0c
Merge branch 'trunk' into wpcli
crstauf Oct 3, 2024
da3f2fe
Merge branch 'trunk' into wpcli
crstauf Oct 23, 2024
be1ba03
Merge branch 'trunk' into wpcli
crstauf Oct 23, 2024
383acc2
Merge branch 'trunk' into wpcli
crstauf Oct 23, 2024
35ecb49
Merge branch 'trunk' into wpcli
crstauf Oct 25, 2024
28f06cf
Merge branch 'trunk' into wpcli
crstauf Oct 29, 2024
3b5e30d
Merge branch 'trunk' into wpcli
crstauf Oct 30, 2024
11c0e30
Merge branch 'trunk' into wpcli
crstauf Oct 30, 2024
45c32fb
Merge branch 'trunk' into wpcli
crstauf Oct 30, 2024
5ad9e41
Merge branch 'trunk' into wpcli
crstauf Oct 31, 2024
c66f7fa
Merge branch 'trunk' into wpcli
crstauf Nov 1, 2024
0cbaa0b
Merge branch 'trunk' into wpcli
crstauf Nov 2, 2024
e702c92
Merge branch 'trunk' into wpcli
crstauf Nov 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions classes/WP_CLI/Action/Cancel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php

use function \WP_CLI\Utils\get_flag_value;

/**
* WP-CLI command: action-scheduler action cancel
*/
class ActionScheduler_WPCLI_Action_Cancel_Command extends ActionScheduler_WPCLI_Command {

/**
* Execute command.
*
* @uses as_unschedule_action()
* @uses as_unschedule_all_actions()
* @uses $this->print_error()
* @uses $this->print_success()
crstauf marked this conversation as resolved.
Show resolved Hide resolved
* @return void
*/
public function execute() {
$hook = '';
$group = get_flag_value( $this->assoc_args, 'group', '' );
$callback_args = get_flag_value( $this->assoc_args, 'args', null );
$all = get_flag_value( $this->assoc_args, 'all', false );

if ( ! empty( $this->args[0] ) ) {
$hook = $this->args[0];
}

if ( ! empty( $callback_args ) ) {
$callback_args = json_decode( $callback_args, true );
}

if ( $all ) {
$this->cancel_all( $hook, $callback_args, $group );
return;
}

$this->cancel_single( $hook, $callback_args, $group );
}

/**
* Cancel single action.
*
* @param string $hook
* @param array $callback_args
* @param string $group
crstauf marked this conversation as resolved.
Show resolved Hide resolved
* @return void
*/
protected function cancel_single( $hook, $callback_args, $group ) {
if ( empty( $hook ) ) {
\WP_CLI::error( __( 'Please specify hook of action to cancel.', 'action-scheduler' ) );
}

try {
$result = call_user_func( 'as_unschedule_action', $hook, $callback_args, $group );
crstauf marked this conversation as resolved.
Show resolved Hide resolved
} catch ( \Exception $e ) {
crstauf marked this conversation as resolved.
Show resolved Hide resolved
$this->print_error( $e, false );
}

if ( null === $result ) {
$e = new \Exception( __( 'Unable to cancel scheduled action: check the logs.', 'action-scheduler' ) );
$this->print_error( $e, false );
}

$this->print_success( false );
}

/**
* Cancel all actions.
*
* @param string $hook
* @param array $callback_args
* @param string $group
* @return void
*/
protected function cancel_all( $hook, $callback_args, $group ) {
if ( empty( $hook ) && empty( $group ) ) {
\WP_CLI::error( __( 'Please specify hook and/or group of actions to cancel.', 'action-scheduler' ) );
}

try {
$result = call_user_func( 'as_unschedule_all_actions', $hook, $callback_args, $group );
} catch ( \Exception $e ) {
$this->print_error( $e, $multiple );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that it won't throw an exception necessarily even if cancelling failed, there could be an error caught by the try_catch in as_unschedule_action. It would be more reliable to either

  1. check the logs for failed action, or
  2. verify that the action is indeed cancelled, or
  3. modify the as_unschedule_action to return the result value so that we can display it reliably.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to rework this command a bit: realized in its current state actions could not be unscheduled by group only.

}

/**
* Because as_unschedule_all_actions() does not provide a result,
* neither confirm or deny actions cancelled.
*/
\WP_CLI::success( __( 'Request to cancel scheduled actions completed.', 'action-scheduler' ) );
}

/**
* Print a success message.
*
* @return void
*/
protected function print_success() {
\WP_CLI::success( __( 'Scheduled action cancelled.', 'action-scheduler' ) );
}

/**
* Convert an exception into a WP CLI error.
*
* @param \Exception $e The error object.
* @param bool $multiple Boolean if multiple actions.
* @throws \WP_CLI\ExitException
* @return void
*/
protected function print_error( \Exception $e, $multiple ) {
\WP_CLI::error(
sprintf(
/* translators: %1$s: singular or plural %2$s: refers to the exception error message. */
__( 'There was an error cancelling the scheduled %1$s: %2$s', 'action-scheduler' ),
crstauf marked this conversation as resolved.
Show resolved Hide resolved
$multiple ? 'actions' : 'action',
$e->getMessage()
)
);
}

}
137 changes: 137 additions & 0 deletions classes/WP_CLI/Action/Create.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?php

use function \WP_CLI\Utils\get_flag_value;

/**
* WP-CLI command: action-scheduler action create
*/
class ActionScheduler_WPCLI_Action_Create_Command extends ActionScheduler_WPCLI_Command {
crstauf marked this conversation as resolved.
Show resolved Hide resolved

const ASYNC_OPTS = array( 'async', 'now', 0 );

/**
* Execute command.
*
* @uses as_schedule_single_action()
* @uses as_enqueue_async_action()
* @uses as_schedule_recurring_action()
* @uses as_schedule_cron_action()
* @uses $this->print_error()
* @uses $this->print_success()
* @return void
*/
public function execute() {
$hook = $this->args[0];
$schedule_start = $this->args[1];
$callback_args = get_flag_value( $this->assoc_args, 'args', array() );
$group = get_flag_value( $this->assoc_args, 'group', '' );
$interval = absint( get_flag_value( $this->assoc_args, 'interval', 0 ) );
$cron = get_flag_value( $this->assoc_args, 'cron', '' );
$unique = get_flag_value( $this->assoc_args, 'unique', false );
$priority = absint( get_flag_value( $this->assoc_args, 'priority', 10 ) );

if ( ! empty( $callback_args ) ) {
$callback_args = json_decode( $callback_args, true );
}

$function_args = array(
crstauf marked this conversation as resolved.
Show resolved Hide resolved
'start' => 'async',
'cron' => $cron,
'interval' => $interval,
'hook' => $hook,
'callback_args' => $callback_args,
'group' => $group,
'unique' => $unique,
'priority' => $priority,
);

try {
// Generate schedule start if appropriate.
if ( ! in_array( $schedule_start, static::ASYNC_OPTS, true ) ) {
$schedule_start = as_get_datetime_object( $schedule_start );
$function_args['start'] = $schedule_start->format( 'U' );
}
} catch( \Exception $e ) {
\WP_CLI::error( $e->getMessage() );
}

// Default to creating single action.
$action_type = 'single';
$function = 'as_schedule_single_action';

if ( 'async' === $function_args['start'] ) { // Enqueue async action.
$action_type = 'async';
$function = 'as_enqueue_async_action';

$function_args = array_filter(
$function_args,
static function( $key ) {
return in_array( $key, array( 'hook', 'callback_args', 'group', 'unique', 'priority' ), true );
},
ARRAY_FILTER_USE_KEY
);

} else if ( ! empty( $interval ) ) { // Creating recurring action.
$action_type = 'recurring';
$function = 'as_schedule_recurring_action';

} else if ( ! empty( $cron ) ) { // Creating cron action.
$action_type = 'cron';
$function = 'as_schedule_cron_action';
}

$function_args = array_values( $function_args );
vedanshujain marked this conversation as resolved.
Show resolved Hide resolved

try {
$action_id = call_user_func_array( $function, $function_args );
} catch ( \Exception $e ) {
$this->print_error( $e );
}

if ( 0 === $action_id ) {
$e = new \Exception( __( 'Unable to create a scheduled action.', 'action-scheduler' ) );
$this->print_error( $e );
}

$this->print_success( $action_id, $action_type );
}

/**
* Print a success message with the action ID.
*
* @param int $action_id Created action ID.
* @param string $action_type Type of action.
*
* @return void
*/
protected function print_success( $action_id, $action_type ) {
\WP_CLI::success(
sprintf(
/* translators: %1$s: type of action, %2$d: ID of the created action */
__( '%1$s action (%2$d) scheduled.', 'action-scheduler' ),
ucfirst( $action_type ),
$action_id
)
);
}

/**
* Convert an exception into a WP CLI error.
*
* @param \Exception $e The error object.
*
* @throws \WP_CLI\ExitException
*
* @return void
*/
protected function print_error( \Exception $e ) {
\WP_CLI::error(
sprintf(
/* translators: %s refers to the exception error message. */
__( 'There was an error creating the scheduled action: %s', 'action-scheduler' ),
$e->getMessage()
)
);
}

}
102 changes: 102 additions & 0 deletions classes/WP_CLI/Action/Delete.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

/**
* WP-CLI command: action-scheduler action delete
*/
class ActionScheduler_WPCLI_Action_Delete_Command extends ActionScheduler_WPCLI_Command {
crstauf marked this conversation as resolved.
Show resolved Hide resolved

/** @var int[] */
protected $action_ids = array();

/** @var array<string, int> */
protected $action_counts = array(
'deleted' => 0,
'failed' => 0,
'total' => 0,
);

/**
* Construct.
*
* @param string[] $args Positional arguments.
* @param array<string, string> $assoc_args Keyed arguments.
*/
public function __construct( array $args, array $assoc_args ) {
parent::__construct( $args, $assoc_args );

$this->action_ids = array_map( 'absint', $args );
$this->action_counts['total'] = count( $this->action_ids );

add_action( 'action_scheduler_deleted_action', array( $this, 'action__deleted' ) );
crstauf marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Execute.
*
* @uses \ActionScheduler_Store::delete_action()
* @uses \WP_CLI::warning()
* @uses \WP_CLI::success()
* @return void
*/
public function execute() {
$store = \ActionScheduler::store();

$progress_bar = \WP_CLI\Utils\make_progress_bar(
sprintf(
/* translators: %d: number of actions to be deleted */
_n( 'Deleting %d action', 'Deleting %d actions', $this->action_counts['total'], 'action-scheduler' ),
number_format_i18n( $this->action_counts['total'] )
),
$this->action_counts['total']
);

foreach ( $this->action_ids as $action_id ) {
try {
$store->delete_action( $action_id );
} catch ( \Exception $e ) {
$this->action_counts['failed']++;
\WP_CLI::warning( $e->getMessage() );
}

$progress_bar->tick();
}

$progress_bar->finish();

/* translators: %1$d: number of actions deleted */
$format = _n( 'Deleted %1$d action', 'Deleted %1$d actions', $this->action_counts['deleted'], 'action-scheduler' ) .', ';
/* translators: %2$d: number of actions deletions failed */
$format .= _n( '%2$d failure.', '%2$d failures.', $this->action_counts['failed'], 'action-scheduler' );

\WP_CLI::success(
sprintf(
$format,
number_format_i18n( $this->action_counts['deleted'] ),
number_format_i18n( $this->action_counts['failed'] )
)
);
}

/**
* Action: action_scheduler_deleted_action
*
* @param int $action_id Action ID.
* @uses \WP_CLI::debug()
* @return void
*/
public function action__deleted( $action_id ) {
if ( 'action_scheduler_deleted_action' !== current_action() ) {
return;
}

$action_id = absint( $action_id );

if ( ! in_array( $action_id, $this->action_ids, true ) ) {
return;
}

$this->action_counts['deleted']++;
\WP_CLI::debug( sprintf( 'Action %d was deleted.', $action_id ) );
}

}
Loading
Loading