web-dev-qa-db-ja.com

添付ファイルページへのファイル拡張子の追加

前書き

WordPressサイトのメディアライブラリにファイル(stackexchange.jpg)をアップロードするとき、2つの関連リンクがあります。

  1. ファイルへの直接リンク
    http://example.com/wp-content/uploads/stackexchange.jpg

  2. 添付ページ
    http://example.com/stackexchange/

私の質問は2番目のものを扱います:添付ファイルページ

私がやりたいこと

添付ファイルのパーマリンクにファイル拡張子を追加したいのですが。たとえば、

http://example.com/stackexchange/

をお願いします

http://example.com/stackexchange-jpg/

なぜこれが便利だろう

これはいくつかの理由で非常に役に立ちます。一つには、投稿やページなどに使用したい場合には、 ホギングパーマリンク にはならないでしょう。 stackexchange.pngという別のファイルをアップロードします。それで、私は持っているでしょう:
http://example.com/stackexchange-jpg/
そして
http://example.com/stackexchange-png/

また、実際のページにはhttp://example.com/stackexchange/を使用できます。

私はすべてのファイルのスラッグを手動で通過して編集することができることに気づいています。私がやろうと思っていたら、実際にスレッドを作ること。

質問

ファイルがアップロードされるたびにそれが私が探している変更を反映するようにするために私が書くことができる関数はありますか?これでも可能ですか?もしそうなら、どのように私はそれをするのですか?デフォルトのパーマリンクを編集する方法を知っていても、ファイル拡張子部分を追加する方法がわからない場合でも、その情報を使用して作業することができます。

コアファイルを改ざんしなければこれはおそらく不可能であると私は考えています(これは取引を破ることになるでしょう)が、うまくいけばそれは可能です。

読んでくれてありがとう。

2
Leon Williams

素晴らしい質問です。私は自分自身についてこのことを考えていました、そしてあなたの質問は私にそれを掘り下げるよう促しました。

アップロードされたファイルのスラッグ名を修正するために使用できるフィルタwp_insert_attachment_dataがあります。添付ファイルがpost.phpのデータベースに挿入される直前に、添付ファイルに対して呼び出されます。

次のサンプルはスラッグ名にMIMEタイプを追加します。例えば、image-jpgはjpeg画像タイトルに追加されます。

    /**
     * Filter attachment post data before it is added to the database
     *  - Add mime type to post_name to reduce slug collisions
     *
     * @param array $data    Array of santized attachment post data
     * @param array $postarr Array of unsanitized attachment post data
     * @return $data, array of post data
     */
    function filter_attachment_slug($data, $postarr)
    {
        /**
         * Only work on attachment types
         */
        if ( ! array_key_exists( 'post_type', $data ) || 'attachment' != $data['post_type'] )
            return $data;

        /**
         * Add mime type to the post title to build post-name
         */
        $post_title = array_key_exists( 'post_title', $data ) ? $data['post_title'] : $postarr['post_title'];
        $post_mime_type = array_key_exists( 'post_mime_type', $data ) ? $data['post_mime_type'] : $postarr['post_mime_type'];
        $post_mime_type = str_replace( '/', '-', $post_mime_type );
        $post_name = sanitize_title( $post_title . '-' . $post_mime_type );

        /**
         * Generate unique slug for post name
         */
        $post_ID = array_key_exists( 'ID', $data ) ? $data['ID'] : $postarr['ID'];
        $post_status = array_key_exists( 'post_status', $data ) ? $data['post_status'] : $postarr['post_status'];
        $post_type = array_key_exists( 'post_type', $data ) ? $data['post_type'] : $postarr['post_type'];
        $post_parent = array_key_exists( 'post_parent', $data ) ? $data['post_parent'] : $postarr['post_parent'];

        $post_name = wp_unique_post_slug( $post_name, $post_ID, $post_status, $post_type, $post_parent );
        $data['post_name'] = $post_name;

        return $data;
    }

    /**
     * Adjust slug for uploaded files to include mime type
     */
    add_filter( 'wp_insert_attachment_data', 'filter_attachment_slug', 10, 2 );
1
KenB

これは KenBの答え を拡張したものです。マイナーな編集を加えました。

違い

メディアライブラリにアップロードされているファイルstackexchange.pngを考えてみましょう。

KenB独自のソリューション

結果:http://example.com/stackexchange-image-png/
これは投稿をデータベースにタップし、post_mime_type列から取得します。この場合、結果はimage/pngになります。

+これらの編集

結果:http://example.com/stackexchange-png/
post_mime_typeから引き出すのではなく、guidから引き出すことができ(この場合、結果はhttp://example.com/wp-content/uploads/stackexchange.pngになります)、それからファイル拡張子以外のすべてを取り除き、それを使って作業することができます。

コード

それで今私はその解決策とこれの違いを説明したので、ここにそれを行う方法があります。私は DisgruntledGoatとStackOverflow の質問に対するredanimalwarの答えを少し編集しました。

KenBのソリューションで無効にしたものはすべてコードに残しましたが、コメントアウトしただけなので、実際に行ったことを確認できます。

/**
 * This finds the last '.' in a URI and returns the string after that.
 * For example, in the case of 'example.com/photo.jpg', 'jpg' is returned. 
 *
 * @author DisgruntledGoat
 * @author redanimalwar
 *
 * @link https://stackoverflow.com/a/1361752/5675729
 */
function get_file_extension($uri) {
    $position = strrpos($uri, '.');
    $extension = $position === false ? $uri : substr($uri, $position + 1);
    return $extension;
}

/**
 * Filter attachment post data before it is added to the database
 *  - Add mime type to post_name to reduce slug collisions
 *
 * @author KenB
 *
 * @link https://wordpress.stackexchange.com/a/238205/88601 Original solution
 * @link https://wordpress.stackexchange.com/a/238291/88601 This variation
 *
 * @param array $data    Array of santized attachment post data
 * @param array $postarr Array of unsanitized attachment post data
 *
 * @return $data, array of post data
 */
function filter_attachment_slug($data, $postarr) {
    /**
     * Only work on attachment types
     */
    if ( ! array_key_exists( 'post_type', $data ) || 'attachment' != $data['post_type'] )
        return $data;

    /**
     * Add mime type to the post title to build post-name
     */
    $post_title = array_key_exists( 'post_title', $data ) ? $data['post_title'] : $postarr['post_title'];

    /**
     * This was in KenB's original solution, but was removed by Leon Williams,
     * as this version does not deal with the MIME type.
     */
    //$post_mime_type = array_key_exists( 'post_mime_type', $data ) ? $data['post_mime_type'] : $postarr['post_mime_type'];

    /**
     * This this takes the MIME type, for example, 'image/jpg', into 'image-jpg'.
     * This was in KenB's original solution, but was removed by Leon Williams,
     * as this version does not deal with the MIME type.
     */
    //$post_mime_type = str_replace( '/', '-', $post_mime_type );

    /**
     * Access the 'guid' column from the database (which retrieves the link to the file),
     * then send it to get_file_extension().
     *
     * @author Leon Williams
     */
    $post_file_extention = get_file_extension($postarr['guid']);

    // Instead of tacking on the MIME type, tack on the file extension that we just obtained.
    $post_name = sanitize_title( $post_title . '-' /*. $post_mime_type*/ . $post_file_extention);

    /**
     * Generate unique slug for post name
     */
    $post_ID = array_key_exists( 'ID', $data ) ? $data['ID'] : $postarr['ID'];
    $post_status = array_key_exists( 'post_status', $data ) ? $data['post_status'] : $postarr['post_status'];
    $post_type = array_key_exists( 'post_type', $data ) ? $data['post_type'] : $postarr['post_type'];
    $post_parent = array_key_exists( 'post_parent', $data ) ? $data['post_parent'] : $postarr['post_parent'];

    $post_name = wp_unique_post_slug( $post_name, $post_ID, $post_status, $post_type, $post_parent );
    $data['post_name'] = $post_name;

    return $data;
}

/**
 * Adjust slug for uploaded files to include file extension
 */
add_filter( 'wp_insert_attachment_data', 'filter_attachment_slug', 10, 2 );

代替方法(guidの代わりにpost_mime_typeを使用)

image/pngからpngを外すこともできます(/の代わりにget_file_extension().を検索させる)。これも同様に機能します。これで、私が持っている方法で、他のリンクにもget_file_extension()を使うことができます。

注意の言葉

ちょっとしたテストで、私はオリジナルのソリューションでもこのバージョンでも、添付ファイルの編集中に[更新]ボタンを押すたびにこのフィルタも起動することを発見しました

たとえば、example.pngという名前の添付ファイルを編集していて、そのカスタムスラッグがexample-file-slugであるとします(以前にそのカスタムスラッグを付けたとします)。今日、あなたは説明を編集していて、説明が終わって "Update"を押すと、このフィルタが起動し、自動的にスラッグをexample-file-slugからexample-pngに変更します。説明を更新することに加えて。あなたが前に戻ってスラッグを他の何かに変更しようとすると、再び、あなたが "Update"を押したときにフィルタが起動し、スラッグを変更しようとするあなたの試みを無効にします。

これは個人的には問題ありませんが、他の人にとっては考慮すべきことかもしれません。

回避策
スラッグ名を変更したい場合は、このフィルタを無効にして(コメントアウトして)、添付ファイルへの変更を保存してから、再度フィルタを有効にする必要があります。あるいは、データベースを直接編集することもできます。

解決策をコーディングする方法はあると確信していますが、現在は解決方法がありません。


これらの素晴らしい人々のおかげで:

0
Leon Williams