] * : exact | prefix | regex. * * [--active] * : Only active rows. * * [--per-page=] * : Rows per page (default 20). * * [--page=] * : Page number (default 1). * * [--format=] * : table | csv | json | yaml. * * @since 4.0.0 * * @param array $args Positional args. * @param array $assoc Assoc args. * * @return void */ public function list( array $args, array $assoc ): void { $perPage = (int) ( $assoc['per-page'] ?? 20 ); $page = (int) ( $assoc['page'] ?? 1 ); $query = [ 'number' => max( 1, $perPage ), 'offset' => ( max( 1, $page ) - 1 ) * max( 1, $perPage ), 'orderby' => 'id', 'order' => 'DESC', ]; if ( isset( $assoc['match-type'] ) ) { $query['match_type'] = (string) $assoc['match-type']; } if ( isset( $assoc['active'] ) ) { $query['is_active'] = 1; } $result = RedirectsModel::paginate( $query ); $rows = array_map( static function ( $row ) { return [ 'id' => (int) $row->id, 'source' => (string) $row->source, 'match' => (string) $row->match_type, 'target' => 'page' === $row->target_type ? '(page #' . (int) $row->target_page_id . ')' : (string) $row->target_url, 'type' => (int) $row->redirect_type, 'active' => $row->is_active ? 'yes' : 'no', 'hits' => (int) $row->hits, ]; }, $result['items'] ); $this->printRows( $assoc, $rows, [ 'id', 'source', 'match', 'target', 'type', 'active', 'hits' ] ); WP_CLI::log( sprintf( /* translators: 1: shown, 2: total */ __( 'Showing %1$d of %2$d redirects.', '404-to-301' ), count( $rows ), (int) $result['total'] ) ); } /** * Show a single redirect. * * ## OPTIONS * * * : Redirect id. * * [--format=] * : table | csv | json | yaml. * * @since 4.0.0 * * @param array $args Positional args. * @param array $assoc Assoc args. * * @return void */ public function get( array $args, array $assoc ): void { $id = (int) ( $args[0] ?? 0 ); $row = new RedirectsModel( $id ); if ( ! $row->exists() ) { WP_CLI::error( __( 'Redirect not found.', '404-to-301' ) ); } $this->printRows( $assoc, [ [ 'id' => (int) $row->id, 'source' => (string) $row->source, 'match_type' => (string) $row->match_type, 'target_type' => (string) $row->target_type, 'target_url' => (string) $row->target_url, 'target_page_id' => $row->target_page_id, 'redirect_type' => (int) $row->redirect_type, 'is_active' => (int) $row->is_active, 'hits' => (int) $row->hits, 'created_at' => $row->created_at, 'updated_at' => $row->updated_at, ], ], [ 'id', 'source', 'match_type', 'target_type', 'target_url', 'target_page_id', 'redirect_type', 'is_active', 'hits', 'created_at', 'updated_at', ] ); } /** * Create a new redirect. * * ## OPTIONS * * --source= * : Source URL or pattern. * * --target= * : Destination URL. * * [--type=] * : 301, 302 or 307 (default 301). * * [--match-type=] * : exact | prefix | regex (default exact). * * [--inactive] * : Create the row but leave it inactive. * * [--notes=] * : Optional admin notes. * * @since 4.0.0 * * @param array $args Positional args. * @param array $assoc Assoc args. * * @return void */ public function create( array $args, array $assoc ): void { $source = (string) ( $assoc['source'] ?? '' ); $target = (string) ( $assoc['target'] ?? '' ); if ( '' === $source || '' === $target ) { WP_CLI::error( __( '--source and --target are both required.', '404-to-301' ) ); } $row = new RedirectsModel(); $row->fill( [ 'source' => $source, 'target_type' => 'link', 'target_url' => $target, 'redirect_type' => (int) ( $assoc['type'] ?? 301 ), 'match_type' => (string) ( $assoc['match-type'] ?? 'exact' ), 'is_active' => isset( $assoc['inactive'] ) ? 0 : 1, 'notes' => isset( $assoc['notes'] ) ? (string) $assoc['notes'] : null ] )->save(); $id = (int) ( $row->id ?? 0 ); if ( 0 < $id ) { WP_CLI::success( sprintf( /* translators: %d: id */ __( 'Redirect created (id %d).', '404-to-301' ), $id ) ); } else { WP_CLI::error( __( 'Could not create the redirect.', '404-to-301' ) ); } } /** * Update a redirect. * * ## OPTIONS * * * : Redirect id. * * [--source=] * : New source. * * [--target=] * : New target URL. * * [--type=] * : New redirect status (301/302/307). * * [--match-type=] * : New match type. * * [--active=] * : 1 / 0 — flip the active state. * * [--notes=] * : New notes. * * @since 4.0.0 * * @param array $args Positional args. * @param array $assoc Assoc args. * * @return void */ public function update( array $args, array $assoc ): void { $id = (int) ( $args[0] ?? 0 ); $data = []; foreach ( [ 'source', 'target', 'type', 'match-type', 'active', 'notes' ] as $key ) { if ( ! isset( $assoc[ $key ] ) ) { continue; } switch ( $key ) { case 'target': $data['target_url'] = (string) $assoc[ $key ]; break; case 'type': $data['redirect_type'] = (int) $assoc[ $key ]; break; case 'match-type': $data['match_type'] = (string) $assoc[ $key ]; break; case 'active': $data['is_active'] = (int) (bool) $assoc[ $key ]; break; case 'notes': case 'source': $data[ $key ] = (string) $assoc[ $key ]; break; default: // Unknown keys are dropped rather than trusted. break; } } if ( empty( $data ) ) { WP_CLI::warning( __( 'Nothing to update — pass at least one --field.', '404-to-301' ) ); return; } $row = new RedirectsModel( $id ); if ( $row->exists() ) { $row->fill( $data )->save(); WP_CLI::success( sprintf( /* translators: %d: id */ __( 'Redirect #%d updated.', '404-to-301' ), $id ) ); } else { WP_CLI::error( __( 'Could not update the redirect.', '404-to-301' ) ); } } /** * Delete one or more redirects. * * ## OPTIONS * * [...] * : One or more redirect ids. * * [--all] * : Delete every redirect (asks for confirmation). * * [--yes] * : Skip the confirmation prompt for `--all`. * * @since 4.0.0 * * @param array $args Positional args. * @param array $assoc Assoc args. * * @return void */ public function delete( array $args, array $assoc ): void { if ( ! empty( $assoc['all'] ) ) { WP_CLI::confirm( __( 'Delete every redirect?', '404-to-301' ), $assoc ); $count = RedirectsModel::deleteWhere(); WP_CLI::success( sprintf( /* translators: %d: rows */ __( 'Deleted %d redirects.', '404-to-301' ), $count ) ); return; } $deleted = 0; foreach ( $args as $id ) { $row = new RedirectsModel( (int) $id ); if ( $row->exists() ) { $row->delete(); ++$deleted; } } WP_CLI::success( sprintf( /* translators: %d: rows */ __( 'Deleted %d redirects.', '404-to-301' ), $deleted ) ); } }