WordPressで不要なテーマを管理画面から一括削除する方法

Cocoonカスタマイズ集
この記事は約9分で読めます。
記事内に広告が含まれています。

はじめに

以下の記事では、WordPressで不要なテーマを管理画面から非表示にする方法を紹介しました。

非表示にするだけでも管理画面はスッキリしますが、「もう絶対に使わないテーマ」や「サーバーの容量を圧迫している古いテーマ」は、直接削除して整理したい場面もあります。

しかし、WordPress標準の機能ではテーマを1つずつ詳細画面から削除していく必要があり、数が多くなると非常に手間がかかります。

そこで、安全に外観→テーマから不要なテーマを一括削除します。

この記事では、この方法について説明します。

完成イメージ

実装手順

以下のコードをfunctions.phpに追加します。

// 管理画面にメニューを追加
add_action('admin_menu', function () {
  add_theme_page(
    'テーマ一括削除',
    'テーマ一括削除',
    'delete_themes',
    'bulk_theme_delete',
    'bulk_theme_delete'
  );
});


/**
 * 管理画面ページを出力
 *
 * @return void
 */
if (!function_exists('bulk_theme_delete')):
function bulk_theme_delete() {
  // 権限チェック
  if (!current_user_can('delete_themes')) {
    wp_die('このページにアクセスする権限がありません。');
  }

  // インストールされている全テーマ情報を取得
  $all_themes = wp_get_themes();

  // 現在有効化されているメインテーマの情報を取得
  $current_theme = wp_get_theme();

  // 保護対象となる有効化中のテーマを配列に保持
  $active_stylesheets = [$current_theme->get_stylesheet()];

  // 親テーマが存在する場合は親テーマも保護対象に追加
  if ($current_theme->parent()) {
    $active_stylesheets[] = $current_theme->parent()->get_stylesheet();
  }

  ?>
  <div class="wrap">
    <div class="theme-delete">
      <h1>テーマ一括削除</h1>
      <p>不要なテーマにチェックを入れて「テーマを削除」ボタンを押してください。</p>

      <?php settings_errors('bulk_theme_delete_msg'); ?>

      <form method="post" action="" onsubmit="return confirm('選択したテーマを本当に削除しますか?');">
        <?php wp_nonce_field('bulk_theme_delete_action', 'bulk_theme_delete_nonce'); ?>

        <table class="wp-list-table widefat fixed striped">
          <thead>
            <tr>
              <td class="manage-column column-cb check-column"></td>
              <th>テーマ名</th>
              <th>ディレクトリ名</th>
              <th>バージョン</th>
              <th>ステータス</th>
            </tr>
          </thead>
          <tbody>
            <?php foreach ($all_themes as $stylesheet => $theme): ?>
              <?php $is_active = in_array($stylesheet, $active_stylesheets, true); ?>
              <tr>
                <th scope="row" class="check-column">
                  <?php if (!$is_active): ?>
                    <input type="checkbox" name="bulk_theme_delete_themes[]" value="<?php echo esc_attr($stylesheet); ?>" class="theme-delete__checkbox">
                  <?php endif; ?>
                </th>
                <td><strong><?php echo esc_html($theme->get('Name')); ?></strong></td>
                <td><code><?php echo esc_html($stylesheet); ?></code></td>
                <td><?php echo esc_html($theme->get('Version')); ?></td>
                <td>
                  <?php if ($is_active): ?>
                    <span class="theme-delete__status theme-delete__status--active">使用中</span>
                  <?php else: ?>
                    <span class="theme-delete__status">停止中</span>
                  <?php endif; ?>
                </td>
              </tr>
            <?php endforeach; ?>
          </tbody>
        </table>

        <p class="theme-delete__submit-wrap">
          <input type="submit" name="bulk_theme_delete_submit" class="button button-primary" value="テーマを削除">
        </p>
      </form>
    </div>
  </div>
  <?php
}
endif;


// 管理画面からの設定データ更新
add_action('admin_init', function () {
  if ('POST' !== $_SERVER['REQUEST_METHOD'] || !isset($_POST['bulk_theme_delete_submit'])) {
    return;
  }

  // nonceチェック
  check_admin_referer('bulk_theme_delete_action', 'bulk_theme_delete_nonce');

  // 権限チェック
  if (!current_user_can('delete_themes')) {
    wp_die('この操作を行う権限がありません。');
  }

  // 選択されたチェックボックスの値を取得
  if (empty($_POST['bulk_theme_delete_themes']) || !is_array($_POST['bulk_theme_delete_themes'])) {
    add_settings_error(
      'bulk_theme_delete_msg',
      'settings_warning',
      '削除対象のテーマが選択されていません。',
      'warning'
    );
    return;
  }

  // 現在有効化されているテーマの情報を取得
  $current_theme = wp_get_theme();

  // 保護対象となる有効化中のテーマを配列に保持
  $active_stylesheets = [$current_theme->get_stylesheet()];

  // 親テーマが存在する場合は親テーマも保護対象に追加
  if ($current_theme->parent()) {
    $active_stylesheets[] = $current_theme->parent()->get_stylesheet();
  }

  $deleted_count = 0;
  $error_count   = 0;

  foreach ($_POST['bulk_theme_delete_themes'] as $stylesheet) {
    $stylesheet = sanitize_text_field($stylesheet);

    // 有効化中のテーマは絶対に削除しない
    if (in_array($stylesheet, $active_stylesheets, true)) {
      continue;
    }

    $result = delete_theme($stylesheet);

    if (is_wp_error($result)) {
      $error_count++;
    } else {
      $deleted_count++;
    }
  }

  if ($deleted_count > 0) {
    // テーマキャッシュをクリア
    wp_clean_themes_cache();

    add_settings_error(
      'bulk_theme_delete_msg',
      'settings_updated',
      $deleted_count . '件のテーマを削除しました。',
      'updated'
    );
  }

  if ($error_count > 0) {
    add_settings_error(
      'bulk_theme_delete_msg',
      'settings_error',
      $error_count . '件のテーマの削除に失敗しました。',
      'error'
    );
  }
});


// 管理画面用JS・CSSを追加
add_action('admin_enqueue_scripts', function ($hook_suffix) {
  if (($_GET['page'] ?? '') !== 'bulk_theme_delete') {
    return;
  }

  ob_start();
  ?>
  .theme-delete .column-cb {
    width: 2em;
  }

  .theme-delete .theme-delete__submit-wrap {
    margin-top: 15px;
  }

  .theme-delete__status--active {
    background-color: #2271b1;
    color: #fff;
    padding: 2px 8px;
    border-radius: 3px;
    font-size: 11px;
  }
  <?php
  wp_add_inline_style('wp-admin', ob_get_clean());
});

さいごに

今回紹介した方法を使えば、標準機能では1つずつしか消せないWordPressのテーマを、管理画面からまとめて安全に一括削除できます。
使用中のメインテーマや親テーマは自動的に保護されるため、誤ってサイトの表示を崩してしまう心配もありません。
増えすぎたテーマを整理してサーバーや管理画面をスッキリ保ちたいときに、ぜひ活用してみてください。

タイトルとURLをコピーしました