239 lines
5.7 KiB
PHP
239 lines
5.7 KiB
PHP
<?php
|
|
/**
|
|
* WP-CLI command handler.
|
|
*
|
|
* @package MediaRightsAudit\CLI
|
|
*/
|
|
|
|
namespace MediaRightsAudit\CLI;
|
|
|
|
use MediaRightsAudit\Core\Database;
|
|
use MediaRightsAudit\External\ExternalScanner;
|
|
use MediaRightsAudit\Internal\AttachmentIndexer;
|
|
use MediaRightsAudit\Internal\UsageScanner;
|
|
|
|
/**
|
|
* WP-CLI commands for Media Audit.
|
|
*
|
|
* ## EXAMPLES
|
|
*
|
|
* # Install or repair database tables.
|
|
* $ wp mra install
|
|
*
|
|
* @package MediaRightsAudit\CLI
|
|
*/
|
|
class Command {
|
|
|
|
/**
|
|
* Creates or repairs the plugin database tables.
|
|
*
|
|
* Safe to run multiple times. Uses dbDelta internally so existing tables
|
|
* are only altered when the schema has changed.
|
|
*
|
|
* ## EXAMPLES
|
|
*
|
|
* $ wp mra install
|
|
* Success: Media Audit tables ready. DB version: 1.0.0
|
|
*
|
|
* @subcommand install
|
|
*
|
|
* @return void
|
|
*/
|
|
public function install(): void {
|
|
Database::create_tables();
|
|
update_option( 'robotstxt_mediaaudit_db_version', ROBOTSTXT_MEDIAAUDIT_DB_VERSION );
|
|
|
|
\WP_CLI::success(
|
|
sprintf(
|
|
/* translators: %s: DB version number */
|
|
__( 'Media Audit tables ready. DB version: %s', 'robotstxt-mediaaudit' ),
|
|
ROBOTSTXT_MEDIAAUDIT_DB_VERSION
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Displays the current plugin and schema versions.
|
|
*
|
|
* ## EXAMPLES
|
|
*
|
|
* $ wp mra status
|
|
*
|
|
* @subcommand status
|
|
*
|
|
* @return void
|
|
*/
|
|
public function status(): void {
|
|
$raw = get_option( 'robotstxt_mediaaudit_db_version', 'not installed' );
|
|
$stored = is_string( $raw ) ? $raw : 'not installed';
|
|
|
|
\WP_CLI::line(
|
|
sprintf(
|
|
/* translators: %s: plugin version */
|
|
__( 'Plugin version : %s', 'robotstxt-mediaaudit' ),
|
|
ROBOTSTXT_MEDIAAUDIT_VERSION
|
|
)
|
|
);
|
|
\WP_CLI::line(
|
|
sprintf(
|
|
/* translators: %s: DB version number */
|
|
__( 'DB version : %s', 'robotstxt-mediaaudit' ),
|
|
$stored
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Scans the media library for internal attachment usage.
|
|
*
|
|
* Runs indexing and usage scanning in a loop until all attachments are processed.
|
|
*
|
|
* ## OPTIONS
|
|
*
|
|
* [--batch=<size>]
|
|
* : Number of attachments to process per iteration.
|
|
* ---
|
|
* default: 50
|
|
* ---
|
|
*
|
|
* ## EXAMPLES
|
|
*
|
|
* $ wp mra scan-internal
|
|
* $ wp mra scan-internal --batch=100
|
|
*
|
|
* @subcommand scan-internal
|
|
*
|
|
* @param array<string> $args Positional arguments (unused).
|
|
* @param array<string> $assoc_args Named arguments.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function scan_internal( array $args, array $assoc_args ): void {
|
|
$batch_size = isset( $assoc_args['batch'] ) ? intval( $assoc_args['batch'] ) : 50;
|
|
if ( $batch_size < 1 ) {
|
|
$batch_size = 50;
|
|
}
|
|
|
|
// --- Indexing phase ---
|
|
\WP_CLI::log( __( 'Indexing attachments…', 'robotstxt-mediaaudit' ) );
|
|
$total_indexed = 0;
|
|
|
|
do {
|
|
$indexed = AttachmentIndexer::index_batch( $batch_size );
|
|
$total_indexed += $indexed;
|
|
$pending = AttachmentIndexer::get_pending_count();
|
|
|
|
if ( $indexed > 0 ) {
|
|
\WP_CLI::log(
|
|
sprintf(
|
|
/* translators: 1: newly indexed count, 2: remaining count */
|
|
__( 'Indexed %1$d (%2$d remaining)', 'robotstxt-mediaaudit' ),
|
|
$indexed,
|
|
$pending
|
|
)
|
|
);
|
|
}
|
|
} while ( $indexed > 0 && $pending > 0 );
|
|
|
|
\WP_CLI::success(
|
|
sprintf(
|
|
/* translators: %d: total indexed count */
|
|
__( 'Indexing complete. %d attachments in index.', 'robotstxt-mediaaudit' ),
|
|
AttachmentIndexer::get_indexed_count()
|
|
)
|
|
);
|
|
|
|
// --- Usage scanning phase ---
|
|
\WP_CLI::log( __( 'Scanning usage…', 'robotstxt-mediaaudit' ) );
|
|
$total_scanned = 0;
|
|
|
|
do {
|
|
$scanned = UsageScanner::scan_batch( $batch_size );
|
|
$total_scanned += $scanned;
|
|
$pending = UsageScanner::get_pending_count();
|
|
|
|
if ( $scanned > 0 ) {
|
|
\WP_CLI::log(
|
|
sprintf(
|
|
/* translators: 1: scanned count, 2: remaining count */
|
|
__( 'Scanned %1$d (%2$d remaining)', 'robotstxt-mediaaudit' ),
|
|
$scanned,
|
|
$pending
|
|
)
|
|
);
|
|
}
|
|
} while ( $scanned > 0 && $pending > 0 );
|
|
|
|
\WP_CLI::success(
|
|
sprintf(
|
|
/* translators: %d: total scanned count */
|
|
__( 'Scan complete. %d attachments scanned.', 'robotstxt-mediaaudit' ),
|
|
$total_scanned
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Runs external reverse-image-search scans via all configured providers.
|
|
*
|
|
* Promotes any 'pending' attachments to 'queued' before scanning, then
|
|
* processes all queued items synchronously. Requires API keys to be configured.
|
|
*
|
|
* ## OPTIONS
|
|
*
|
|
* [--batch=<size>]
|
|
* : Number of attachments to process per iteration.
|
|
* ---
|
|
* default: 10
|
|
* ---
|
|
*
|
|
* ## EXAMPLES
|
|
*
|
|
* $ wp mra scan-external
|
|
* $ wp mra scan-external --batch=5
|
|
*
|
|
* @subcommand scan-external
|
|
*
|
|
* @param array<string> $args Positional arguments (unused).
|
|
* @param array<string> $assoc_args Named arguments.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function scan_external( array $args, array $assoc_args ): void {
|
|
$batch_size = isset( $assoc_args['batch'] ) ? (int) $assoc_args['batch'] : 10;
|
|
if ( $batch_size < 1 ) {
|
|
$batch_size = 10;
|
|
}
|
|
|
|
\WP_CLI::log( __( 'Running external scans…', 'robotstxt-mediaaudit' ) );
|
|
|
|
ExternalScanner::queue_all_pending();
|
|
|
|
$total_scanned = 0;
|
|
|
|
do {
|
|
$scanned = ExternalScanner::scan_batch( $batch_size );
|
|
$total_scanned += $scanned;
|
|
$pending = ExternalScanner::get_pending_count();
|
|
|
|
if ( $scanned > 0 ) {
|
|
\WP_CLI::log(
|
|
sprintf(
|
|
/* translators: 1: scanned count, 2: remaining count */
|
|
__( 'Scanned %1$d (%2$d remaining)', 'robotstxt-mediaaudit' ),
|
|
$scanned,
|
|
$pending
|
|
)
|
|
);
|
|
}
|
|
} while ( $scanned > 0 && $pending > 0 );
|
|
|
|
\WP_CLI::success(
|
|
sprintf(
|
|
/* translators: %d: total scanned count */
|
|
__( 'External scan complete. %d attachments processed.', 'robotstxt-mediaaudit' ),
|
|
$total_scanned
|
|
)
|
|
);
|
|
}
|
|
}
|