This commit is contained in:
Javier Casares 2026-06-03 06:24:03 +00:00
commit 6708bbb67f
43 changed files with 8342 additions and 0 deletions

239
includes/CLI/Command.php Normal file
View file

@ -0,0 +1,239 @@
<?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
)
);
}
}