301 redirects with import from Simple 301 Redirects

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Alex Cube
2026-10-25 17:14:17 +03:00
co-authored by Claude Opus 5.5
parent 6793fbfc6d
commit cc64a2fd76
+48 -3
View File
@@ -28,6 +28,7 @@ function seojak_defaults(): array {
'default_image' => '',
'twitter_site' => '',
'same_as' => '',
'redirects' => '',
'noindex_category' => 1,
'noindex_tag' => 1,
'noindex_author' => 1,
@@ -347,12 +348,32 @@ add_filter( 'wp_sitemaps_posts_query_args', function ( $args ) {
return $args;
} );
// Старый адрес карты сайта и ключ IndexNow.
/* ===================== Редиректы ===================== */
/** Правила из настроек: «/откуда/ куда» по строке, # — комментарий. Ключ — путь без крайних слешей, в нижнем регистре. */
function seojak_redirects(): array {
$rules = array();
foreach ( explode( "\n", (string) seojak_opt( 'redirects' ) ) as $line ) {
$parts = preg_split( '/\s+/', trim( $line ) );
if ( 2 === count( $parts ) && '#' !== $parts[0][0] ) {
$rules[ mb_strtolower( trim( rawurldecode( $parts[0] ), '/' ) ) ] = $parts[1];
}
}
return $rules;
}
// Старый адрес карты сайта, ключ IndexNow и свои редиректы.
add_action( 'template_redirect', function () {
$path = trim( rawurldecode( (string) wp_parse_url( $_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH ) ), '/' );
$to = seojak_redirects()[ mb_strtolower( $path ) ] ?? '';
if ( $to ) {
// Внешний адрес — как есть (партнёрские ссылки), свой путь — от корня сайта.
wp_redirect( preg_match( '#^https?://#i', $to ) ? $to : home_url( '/' . ltrim( $to, '/' ) ), 301, 'SEOJak' ); // phpcs:ignore WordPress.Security.SafeRedirect -- адреса задаёт админ
exit;
}
if ( defined( 'AIOSEO_VERSION' ) ) {
return;
}
$path = trim( (string) wp_parse_url( $_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH ), '/' );
if ( in_array( $path, array( 'sitemap.xml', 'sitemap_index.xml', 'post-sitemap.xml', 'page-sitemap.xml' ), true ) ) {
wp_safe_redirect( home_url( '/wp-sitemap.xml' ), 301 );
exit;
@@ -504,7 +525,7 @@ add_action( 'admin_init', function () {
$out[ $key ] = empty( $in[ $key ] ) ? 0 : 1;
} elseif ( in_array( $key, array( 'person_image', 'default_image' ), true ) ) {
$out[ $key ] = esc_url_raw( $in[ $key ] ?? '' );
} elseif ( in_array( $key, array( 'home_description', 'same_as' ), true ) ) {
} elseif ( in_array( $key, array( 'home_description', 'same_as', 'redirects' ), true ) ) {
$out[ $key ] = sanitize_textarea_field( $in[ $key ] ?? '' );
} else {
$out[ $key ] = sanitize_text_field( $in[ $key ] ?? '' );
@@ -551,6 +572,9 @@ function seojak_settings_page() {
<?php endforeach; ?>
<tr><th><label for="sj-same_as">Профили автора в соцсетях</label></th>
<td><textarea class="large-text" rows="3" id="sj-same_as" name="<?php echo esc_attr( "{$name}[same_as]" ); ?>" placeholder="По одному адресу в строке"><?php echo esc_textarea( $o['same_as'] ); ?></textarea></td></tr>
<tr><th><label for="sj-redirects">Редиректы 301</label></th>
<td><textarea class="large-text code" rows="6" id="sj-redirects" name="<?php echo esc_attr( "{$name}[redirects]" ); ?>" placeholder="/старый-адрес/ https://куда.ru/"><?php echo esc_textarea( $o['redirects'] ); ?></textarea>
<p class="description">По правилу в строке: путь на этом сайте, пробел, куда вести (полный адрес или путь). Строки с # — комментарии.</p></td></tr>
<tr><th>Индексация</th><td>
<?php foreach ( $checks as $key => $label ) : ?>
<label><input type="checkbox" name="<?php echo esc_attr( "{$name}[{$key}]" ); ?>" value="1" <?php checked( $o[ $key ] ); ?>> <?php echo esc_html( $label ); ?></label><br>
@@ -621,10 +645,31 @@ register_activation_hook( __FILE__, function () {
add_option( SEOJAK_OPTION, $opts );
}
seojak_import_aioseo();
seojak_import_redirects();
} );
/** Дописывает к своим редиректам правила Simple 301 Redirects, которых ещё нет. Возвращает число добавленных. */
function seojak_import_redirects(): int {
$have = seojak_redirects();
$lines = array();
foreach ( (array) get_option( '301_redirects', array() ) as $from => $to ) {
if ( $to && ! isset( $have[ mb_strtolower( trim( rawurldecode( $from ), '/' ) ) ] ) ) {
$lines[] = "$from $to";
}
}
if ( $lines ) {
$opts = (array) get_option( SEOJAK_OPTION, array() );
$opts['redirects'] = trim( ( $opts['redirects'] ?? '' ) . "\n" . implode( "\n", $lines ) );
update_option( SEOJAK_OPTION, $opts );
}
return count( $lines );
}
if ( defined( 'WP_CLI' ) && WP_CLI ) {
WP_CLI::add_command( 'seojak import-aioseo', function () {
WP_CLI::success( 'Перенесено записей: ' . seojak_import_aioseo() );
} );
WP_CLI::add_command( 'seojak import-redirects', function () {
WP_CLI::success( 'Добавлено редиректов из Simple 301 Redirects: ' . seojak_import_redirects() );
} );
}