WordPressでテーマエディタからファイルが更新できなくなったときの対処【file.phpを更新して解決】

WordPressをアップデートしたことを契機に、テーマエディタやプラグインエディタからファイルを編集できなくなったのですが、その対処方法についてまとめていきたいと思います。（WordPress ver4.9以降で同様の問題が発生する疑惑です。）

#WordPressでphpファイルの更新ができなくなったときの対処
とうことで見出しの通りですが、テーマエディタからファイルを更新しようとすると以下のように怒られてしまいます。

![themeeditor_eroor.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/84d5ecdc-936c-559a-c205-1e4d416d445a.jpeg)

英語が直訳されているのか見事なまでにざっくりコメントでした。実際にはFPT経由するなどして、ホスティングサーバ上のファイルを直に編集することはできるのはさすがに面倒くさいので対処方法について記載していきます。

#【結論】file.phpファイルから一部コメントアウト
ということで解決方法を探していたら、解決策をまとめてくれているWordPressのフォーラム（[Can’t edit main theme php files after upgrading to 4.9](https://wordpress.org/support/topic/cant-edit-main-theme-php-files-after-upgrading-to-4-9/page/4/)）がありました。そちらの内容を参照しながら、対処法を記します。

どうやらアップデートに伴いセキュリティチェックが厳しくなったようで、ファイル更新しようとするとエラーが発生してしまうみたいです。そのエラー処理に該当する部分をコメントアウトするというやり方のため、セキュリティレベルは低減してしまうことを踏まえて自己判断でご対応をお願いします。

**【対処方法】**
`wp-admin/includes/file.php`のファイルから、以下の内容（500行目あたりから約10行）を`/* {当該内容} */`としてコメントアウトします。

```php:file.php
if ($is_active && 'php' === $extension) {
    $scrape_key   = md5(rand());
    $transient    = 'scrape_key_' . $scrape_key;
    $scrape_nonce = strval(rand());
    set_transient($transient, $scrape_nonce, 60); // It shouldn't take more than 60 seconds to make the two loopback requests.

    $cookies       = wp_unslash($_COOKIE);
    $scrape_params = array(
            'wp_scrape_key'   => $scrape_key,
            'wp_scrape_nonce' => $scrape_nonce,
        );
    $headers       = array(
            'Cache-Control' => 'no-cache',
        );

    $sslverify = apply_filters('https_local_ssl_verify', false);

    // Include Basic auth in loopback requests.
    if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
        $headers['Authorization'] = 'Basic ' . base64_encode(wp_unslash($_SERVER['PHP_AUTH_USER']) . ':' . wp_unslash($_SERVER['PHP_AUTH_PW']));
    }

    // Make sure PHP process doesn't die before loopback requests complete.
    set_time_limit(300);

    // Time to wait for loopback requests to finish.
    $timeout = 100;

    $needle_start = "###### wp_scraping_result_start:$scrape_key ######";
    $needle_end   = "###### wp_scraping_result_end:$scrape_key ######";

    // Attempt loopback request to editor to see if user just whitescreened themselves.
    if ($plugin) {
        $url = add_query_arg(compact('plugin', 'file'), admin_url('plugin-editor.php'));
    } elseif (isset($stylesheet)) {
        $url = add_query_arg(
                array(
                    'theme' => $stylesheet,
                    'file'  => $file,
                ),
                admin_url('theme-editor.php')
            );
    } else {
        $url = admin_url();
    }
    $url                    = add_query_arg($scrape_params, $url);
    $r                      = wp_remote_get($url, compact('cookies', 'headers', 'timeout', 'sslverify'));
    $body                   = wp_remote_retrieve_body($r);
    $scrape_result_position = strpos($body, $needle_start);

    $loopback_request_failure = array(
            'code'    => 'loopback_request_failed',
            'message' => __('Unable to communicate back with site to check for fatal errors, so the PHP change was reverted. You will need to upload your PHP file change by some other means, such as by using SFTP.'),
        );
    $json_parse_failure       = array(
            'code' => 'json_parse_error',
        );

    $result = null;
    if (false === $scrape_result_position) {
        $result = $loopback_request_failure;
    } else {
        $error_output = substr($body, $scrape_result_position + strlen($needle_start));
        $error_output = substr($error_output, 0, strpos($error_output, $needle_end));
        $result       = json_decode(trim($error_output), true);
        if (empty($result)) {
            $result = $json_parse_failure;
        }
    }

    // Try making request to homepage as well to see if visitors have been whitescreened.
    if (true === $result) {
        $url                    = home_url('/');
        $url                    = add_query_arg($scrape_params, $url);
        $r                      = wp_remote_get($url, compact('cookies', 'headers', 'timeout'));
        $body                   = wp_remote_retrieve_body($r);
        $scrape_result_position = strpos($body, $needle_start);

        if (false === $scrape_result_position) {
            $result = $loopback_request_failure;
        } else {
            $error_output = substr($body, $scrape_result_position + strlen($needle_start));
            $error_output = substr($error_output, 0, strpos($error_output, $needle_end));
            $result       = json_decode(trim($error_output), true);
            if (empty($result)) {
                $result = $json_parse_failure;
            }
        }
    }

    delete_transient($transient);

    if (true !== $result) {

            // Roll-back file change.
        file_put_contents($real_file, $previous_content);
        if (function_exists('opcache_invalidate')) {
            opcache_invalidate($real_file, true);
        }

        if (! isset($result['message'])) {
            $message = __('Something went wrong.');
        } else {
            $message = $result['message'];
            unset($result['message']);
        }
        return new WP_Error('php_error', $message, $result);
    }
}
```

以上で、無事にテーマエディターからファイルを更新できるようになります。

---
WordPressでテーマエディタからファイルが更新できなくなったときの対処方法についてまとめました。FTP経由での更新は面倒くさいというかたは、ぜひ参考にしてみてください。