get_error_message() );
} else {
$rating = Performance::rating( $result['score'] );
\WP_CLI::log( "{$url} ({$strategy}): {$rating['label']} ({$result['score']}/100)" );
}
}
}
update_option( Performance::LAST_RUN_OPTION, time(), false );
\WP_CLI::success( 'Done.' );
}
/**
* Downloads the Wordfence Intelligence feed and lists vulnerable software.
*
* ## OPTIONS
*
* [--no-sync]
* : Use the data already downloaded.
*
* @param array $args Positional args.
* @param array $assoc_args Named args.
*/
public function vulnerabilities( $args, $assoc_args ) {
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'sync', true ) ) {
$result = Vulnerabilities::sync_now();
if ( is_wp_error( $result ) ) {
\WP_CLI::error( $result->get_error_message() );
}
$state = Vulnerabilities::sync_state();
\WP_CLI::log( sprintf( '%d records read, %d relevant to this site.', $state['total'], $state['indexed'] ) );
}
$exposures = Vulnerabilities::exposures();
if ( ! $exposures ) {
\WP_CLI::success( 'No installed software has known vulnerabilities.' );
return;
}
foreach ( $exposures as $exposure ) {
\WP_CLI::log( sprintf( '%s %s [%s] %s', $exposure['name'], $exposure['version'], $exposure['state'], Vulnerabilities::advice( $exposure ) ) );
foreach ( $exposure['vulns'] as $vuln ) {
\WP_CLI::log( sprintf( ' [%s]%s %s', $vuln['score'], $vuln['mismatch'] ? ' (other edition?)' : '', $vuln['title'] ) );
}
}
\WP_CLI::warning( sprintf( '%d installed component(s) need attention.', count( Vulnerabilities::active_exposures() ) ) );
}
/**
* Adds a manual entry to the log.
*
* ## OPTIONS
*
*
* : What was done.
*
* [--category=]
* : test, security, performance, backup, content, incident or other.
* ---
* default: other
* ---
*
* [--minutes=]
* : Time spent.
*
* [--notes=]
* : Longer description.
*
* ## EXAMPLES
*
* wp maintained-log add "Checked contact form delivery" --category=test --minutes=10
*
* @param array $args Positional args.
* @param array $assoc_args Named args.
*/
public function add( $args, $assoc_args ) {
$category = isset( $assoc_args['category'] ) ? $assoc_args['category'] : 'other';
if ( ! array_key_exists( $category, Log::categories() ) ) {
\WP_CLI::error( 'Unknown category. Use one of: ' . implode( ', ', array_keys( Log::categories() ) ) );
}
$id = Log::add(
array(
'type' => Log::TYPE_MANUAL,
'category' => $category,
'status' => Log::STATUS_SUCCESS,
'title' => $args[0],
'details' => array( 'notes' => isset( $assoc_args['notes'] ) ? sanitize_textarea_field( $assoc_args['notes'] ) : '' ),
'minutes' => isset( $assoc_args['minutes'] ) ? absint( $assoc_args['minutes'] ) : 0,
'source' => Log::SOURCE_CLI,
)
);
$id ? \WP_CLI::success( "Entry #{$id} added." ) : \WP_CLI::error( 'Could not add the entry.' );
}
/**
* Lists log entries.
*
* ## OPTIONS
*
* [--type=]
* : update, check, manual, report, alert or system.
*
* [--limit=]
* : Number of entries.
* ---
* default: 20
* ---
*
* [--format=]
* : table, json, csv or yaml.
* ---
* default: table
* ---
*
* @subcommand list
*
* @param array $args Positional args.
* @param array $assoc_args Named args.
*/
public function list_( $args, $assoc_args ) {
$entries = Log::query(
array(
'type' => isset( $assoc_args['type'] ) ? $assoc_args['type'] : '',
'per_page' => absint( $assoc_args['limit'] ),
)
);
$items = array_map(
static function ( $entry ) {
return array(
'id' => $entry->id,
'created_at' => $entry->created_at,
'type' => $entry->type,
'status' => $entry->status,
'source' => $entry->source,
'minutes' => $entry->minutes,
'title' => $entry->title,
);
},
$entries
);
\WP_CLI\Utils\format_items( $assoc_args['format'], $items, array( 'id', 'created_at', 'type', 'status', 'source', 'minutes', 'title' ) );
}
/**
* Sends the client report for the period since the last report.
*
* ## OPTIONS
*
* [--to=]
* : Send a test copy to these addresses instead of the client.
*
* @param array $args Positional args.
* @param array $assoc_args Named args.
*/
public function report( $args, $assoc_args ) {
$period = Reporter::manual_period();
$report = Reporter::build( $period['from'], $period['to'] );
$result = Reporter::send( $report, isset( $assoc_args['to'] ) ? $assoc_args['to'] : null );
if ( is_wp_error( $result ) ) {
\WP_CLI::error( $result->get_error_message() );
}
if ( ! isset( $assoc_args['to'] ) ) {
update_option( Reporter::LAST_PERIOD_OPTION, $period['to']->format( 'Y-m-d H:i:s' ), false );
}
\WP_CLI::success( 'Report sent.' );
}
/**
* Verifies that no log entry was altered or deleted.
*
* @param array $args Positional args.
* @param array $assoc_args Named args.
*/
public function verify( $args, $assoc_args ) {
$result = Log::verify_chain();
if ( $result['ok'] ) {
\WP_CLI::success( sprintf( '%d entries verified. The log is intact.', $result['checked'] ) );
} else {
\WP_CLI::error( sprintf( 'The log was altered at or before entry #%d.', $result['broken_at'] ) );
}
}
}