Перенаправление URL удалённых записей на другую установку WordPress

Вопрос или проблема

На сайте WordPress http://www.example.com/ (ГЛАВНЫЙ САЙТ) более 540000 постов.

Я хочу уменьшить количество постов, чтобы повысить скорость сайта.

Я установил новый WordPress на http://www.example.com/business-consultants/ (НОВЫЙ САЙТ) и перенес с ГЛАВНОГО САЙТА 3135 постов с тегом ‘Business Consultants’.

В настоящее время я настроил 301 редирект на ГЛАВНОМ САЙТЕ, чтобы перенаправлять посты с тегом ‘Business Consultants’ на новую установку WordPress, то есть

{MAIN_SITE}/{slug} => {NEW_SITE}/business-consultants/{slug}

Что я делаю, так это проверяю тег поста, и если присутствует ‘business-consultants’, перенаправляю запрос на новый сайт, используя wp_safe_redirect().

Проблема в том, что для того, чтобы редирект работал, посты должны быть на ГЛАВНОМ САЙТЕ, и я ищу решение, которое позволит делать редирект даже если посты с тегом ‘Business Consultants’ удалены с главного сайта.

Это сложная задача.

Что я предлагаю – запустить одноразовое задание, которое:

  1. получает все посты с тегом ‘business-consultants’
  2. запускает одноразовое задание*, чтобы сохранить в php-файл массив этих слагов постов
  3. когда запрашивается один из этих URL, перенаправляет на новый URL сайта
  4. удаляет посты

Я напишу весь код в виде плагина.

Я настоятельно рекомендую вам сделать полную резервную копию вашей базы данных перед установкой этого плагина

Сохраните следующий код в файле с именем RedirectDeleted.php, поместите в папку плагинов и активируйте его.

Это займет несколько секунд перед полной загрузкой страницы, но после этого, если вы перейдете на страницу списка ваших постов, вы должны увидеть все посты с тегом ‘business-consultants’, удаленные из WordPress, а также в вашей папке загрузок вы должны увидеть файл php с именем redirect_deleted_business-consultants.php.

Если вы когда-либо зайдете по URL, как http://www.example.com/a-post-slug (где ‘a-post-slug’ — это настоящий слаг поста с тегом ‘business-consultants’), вы должны быть перенаправлены на http://www.example.com/business-consultants/a-post-slug.

Обратите внимание, что если вы когда-либо удалите файл redirect_deleted_business-consultants.php или удалите плагин, редирект больше не будет работать.
Установка плагина в качестве обязательного плагина может быть идеей, чтобы предотвратить удаление.

Например, если у вас есть тег со слагом ‘business-stuff’ и вы хотите перенести его на другую установку WP, просто создайте эту установку по URL http://www.example.com/business-stuff и добавьте ‘business-stuff’ в файл плагина в массив $target_tags (см. ниже).

Код:

<?php
/**
 * Название плагина: RedirectDeletedTag
 * URI плагина: https://wordpress.stackexchange.com/questions/136018/
 */

class RedirectDeletedTag {

  /**
  * Измените эту переменную в соответствии с реальным слагом тега.
  * Ключ - это слаг тега, а значение - базовый URL для редиректа.
  * Если хотите, вы можете добавить другие слаги тегов, которые хотите перенести на отдельные сайты.
  */
  protected $target_tags = array(
    'business-consultants' => 'http://www.example.com/business-consultants/',
  );

  function cacheUrls() {
    if ( ! is_admin() || ! current_user_can( 'install_plugins' ) ) return;
    $t = new ArrayIterator( $this->target_tags );
    while( $t->valid() ) {
      $tag = $t->key();
      if ( $this->shouldCache( $tag ) ) $this->cacheTagUrls( $tag );
      $t->next();
    }
  }

  function redirect() {
    if ( is_admin() ) return;
    $url = $this->getUrl();
    if ( ! empty( $url ) ) {
      $t = new ArrayIterator( $this->target_tags );
      while( $t->valid() ) {
       $this->redirectTag( $t->key(), $url, $t->current() );
       $t->next();
     }
    }
  }

  protected function cacheTagUrls ( $tag ) {
    $args = array( 'post_type' => 'post', 'nopaging' => true, 'tag' => $tag );
    $query = new WP_Query( $args );
    if ( $query->have_posts() ) {
      $slugs = wp_list_pluck( $query->posts, 'post_name' );
      $id_list =  implode( ',',  wp_list_pluck( $query->posts, 'ID') );
      $cache="<?php return array("" . implode('","', $slugs ) . '");';
      if ( @file_put_contents( $this->getCachePath( $tag ), $cache ) !== FALSE ) {
        set_transient( __CLASS__ . $tag, '1' );
        // кэш сохранен, удалите все посты и термины
        global $wpdb;
        $wpdb->query( "DELETE FROM $wpdb->posts WHERE ID IN ($id_list)" );
        $term = get_term_by('slug', $tag, 'post_tag');
        if ( ! empty( $term ) && isset( $term->term_id ) ) {
          wp_delete_term( $term->term_id, 'post_tag' );
        }
      }
    }
  }

  protected function redirectTag( $tag, $url, $base ) {
    if ( file_exists( $this->getCachePath( $tag ) ) ) {
      $cached = (array) include $this->getCachePath( $tag );
      if ( in_array( $url, $cached ) ) {
        wp_redirect( trailingslashit( $base ) . $url );
        exit();
      }
    }
  }

  protected function shouldCache( $tag = '' ) { 
    $should = FALSE;
    if ( is_admin() && current_user_can( 'install_plugins' ) ) {
      $transient = get_transient( __CLASS__ . $tag );
      $file = file_exists( $this->getCachePath( $tag ) );
      $should = empty($transient) && ! $file;
    }
    return $should;
  }

  protected function getCachePath( $tag = '' ) {
    $upload_dir = wp_upload_dir();
    $base = trailingslashit( $upload_dir['basedir'] );
    return  $base . 'redirect_deleted_' . $tag . '.php';
  }

  protected function getUrl() {
    $home_path = trim( parse_url( home_url(), PHP_URL_PATH ), "https://wordpress.stackexchange.com/" );
    $full = trim( str_replace( $home_path, '', add_query_arg( array() ) ), "https://wordpress.stackexchange.com/" );
    $stripped = explode( '?', $full );
    return trim( $stripped[0], "https://wordpress.stackexchange.com/" );
  }

}

$rd = new RedirectDeletedTag();
add_action( 'shutdown', array( $rd, 'cacheUrls' ) );
add_action( 'after_setup_theme', array( $rd, 'redirect' ) );

Плагин доступен как Gist здесь.


* Чтобы запустить одноразовое задание, я буду использовать временную метку плюс проверку, является ли текущий пользователь администратором, также наличие кэш-файла. Если хотите, рассмотрите этот вопрос/ответы, чтобы узнать о различных подходах к одноразовым задачам в WordPress.

Ответ или решение

Решение проблемы редиректа удалённых постов в WordPress на другой сайт

Ваша задача заключается в том, чтобы настроить редирект с удалённых постов на основной сайт WordPress на новый сайт WordPress, что является важной частью для улучшения производительности и скорости загрузки вашего сайта.

Исходные данные

  • У вас есть основной сайт: http://www.example.com/ с более чем 540,000 постами.
  • Вы создали новый сайт: http://www.example.com/business-consultants/, на который перенесли 3135 постов, помеченных тегом ‘Business Consultants’.
  • Вам необходимо настроить 301 редирект, который будет работать даже после удаления постов с основного сайта.

Предложенное решение

Вы можете использовать плагин, который будет выполнять следующие шаги:

  1. Получить все посты с тегом ‘business-consultants’.
  2. Сохранить их в PHP-файле для последующего использования.
  3. Удалить эти посты с основного сайта.
  4. Настроить редирект для каждого из этих постов.

Важно!

Перед началом любых манипуляций обязательно сделайте полную резервную копию базы данных веб-сайта. Это поможет восстановить систему в случае непредвиденных проблем.

Код плагина

Сохраните следующий код в файле RedirectDeleted.php и разместите его в папке плагинов вашего WordPress. После этого активируйте плагин:

<?php
/**
 * Plugin Name: RedirectDeletedTag
 * Plugin URI: https://wordpress.stackexchange.com/questions/136018/
 */

class RedirectDeletedTag {

  // Настройте массив тегов и URL для редиректа.
  protected $target_tags = array(
    'business-consultants' => 'http://www.example.com/business-consultants/',
  );

  function cacheUrls() {
    if (!is_admin() || !current_user_can('install_plugins')) return;
    foreach($this->target_tags as $tag => $url) {
      if ($this->shouldCache($tag)) $this->cacheTagUrls($tag);
    }
  }

  function redirect() {
    if (is_admin()) return;
    $url = $this->getUrl();
    if (!empty($url)) {
      foreach($this->target_tags as $tag => $base) {
        $this->redirectTag($tag, $url, $base);
      }
    }
  }

  protected function cacheTagUrls($tag) {
    $args = array('post_type' => 'post', 'nopaging' => true, 'tag' => $tag);
    $query = new WP_Query($args);
    if ($query->have_posts()) {
      $slugs = wp_list_pluck($query->posts, 'post_name');
      $id_list = implode(',', wp_list_pluck($query->posts, 'ID'));
      $cache="<?php return array(\"" . implode("\",\"", $slugs) . "\");";
      if (@file_put_contents($this->getCachePath($tag), $cache) !== FALSE) {
        set_transient(__CLASS__ . $tag, '1');
        global $wpdb;
        $wpdb->query("DELETE FROM $wpdb->posts WHERE ID IN ($id_list)");
        $term = get_term_by('slug', $tag, 'post_tag');
        if (!empty($term) && isset($term->term_id)) {
          wp_delete_term($term->term_id, 'post_tag');
        }
      }
    }
  }

  protected function redirectTag($tag, $url, $base) {
    if (file_exists($this->getCachePath($tag))) {
      $cached = (array) include $this->getCachePath($tag);
      if (in_array($url, $cached)) {
        wp_redirect(trailingslashit($base) . $url);
        exit();
      }
    }
  }

  protected function shouldCache($tag = '') { 
    return is_admin() && current_user_can('install_plugins') && empty(get_transient(__CLASS__ . $tag)) && !file_exists($this->getCachePath($tag));
  }

  protected function getCachePath($tag = '') {
    $upload_dir = wp_upload_dir();
    return trailingslashit($upload_dir['basedir']) . 'redirect_deleted_' . $tag . '.php';
  }

  protected function getUrl() {
    $full = trim($_SERVER['REQUEST_URI'], '/');
    return trim($full, '/');
  }
}

$rd = new RedirectDeletedTag();
add_action('shutdown', array($rd, 'cacheUrls'));
add_action('after_setup_theme', array($rd, 'redirect'));

Как это работает?

  1. Плагин проверяет наличие постов с указанным тегом и создает файл кэша с их слагами.
  2. При посещении удалённого поста, если в кэше есть соответствующий слаг, производится редирект на новый сайт.

Заключение

Это решение универсально и может быть адаптировано для работы с другими тегами и сайтами. Убедитесь в тестировании на локальной среде перед применением на живом сайте, чтобы избежать негативного влияния на пользователей и SEO.

Оцените материал
Добавить комментарий

Капча загружается...