[WordPress] 日本語ファイル名でアップロードした画像を%エンコーディングしたい


WP Multibyte Patch を有効にしていれば、日本語ファイル名のメディアファイルはよしなに名前を変えてくれます。
ですが、有効にしていなかった場合 `<img src="https://example.com/wp-content/uploads/スクリーンショット.png" >` みたいなタグを書き出してくれることがあって、ちょっと哀しいことになることがあったんです。
`スクリーンショット.png` だけを%エンコードして出力したいなーってときにサクッと書いたプラグインがこちらになります。

```php:image-url-encode.php
<?php
/*
Plugin Name: Image URL Encoder
Plugin URI: http://digitalcube.jp
Description: 本文中の日本語画像URLを%エンコードする
Author: Digitalcube
Version: 1.0
Author URI: http://digitalcube.jp

Copyright 2021 Digitalcube (email : info@digitalcube.jp)

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

$image_url_encode = New imageUrlEncode();
add_filter( 'wp_get_attachment_url', [ $image_url_encode, 'image_url_encode' ] );
add_filter( 'the_content', [ $image_url_encode, 'the_content' ] );
add_filter( 'the_content_feed', [ $image_url_encode, 'the_content' ] );

class imageUrlEncode
{
    public function __construct()
    {
    }

    public function image_url_encode( $image_url )
    {
        return preg_replace_callback(
            '#[^/]+$#',
            function ( $matches ) { return urlencode( $matches[0] ); },
            $image_url
        );
    }

    public function the_content( $content )
    {
        $image_urls = [];

        // <img src>
        if ( preg_match_all( '#<img [^>]*src=[\'"]([^\'"]*)[\'"][^>]*>#', $content, $image_srcs, PREG_SET_ORDER ) )
        {
            foreach ( $image_srcs as $image_src )
            {
                $image_url = trim( $image_src[1] );
                $image_url_encode = $this->image_url_encode( $image_url );
                if ( $image_url !== $image_url_encode )
                {
                    $image_urls[$image_url] = $image_url_encode;
                }
            }
        }

        // <img srcset>
        if ( preg_match_all( '#<img [^>]*srcset=[\'"]([^\'"]*)[\'"][^>]*>#', $content, $image_srcsets, PREG_SET_ORDER ) )
        {
            foreach ( $image_srcsets as $image_srcset )
            {
                $image_srcs = explode( ',', $image_srcset[1] );
                foreach ( $image_srcs as $image_src )
                {
                    $image_url = trim( preg_replace( '# [^ ]+$#', '', $image_src ) );
                    $image_url_encode = $this->image_url_encode( $image_url );
                    if ( $image_url !== $image_url_encode )
                    {
                        $image_urls[$image_url] = $image_url_encode;
                    }
                }
            }
        }

        // replace
        if ( count( $image_urls ) > 0 )
        {
            $content = str_replace( array_keys( $image_urls ), $image_urls, $content );
        }

        return $content;
    }
}
```