web-dev-qa-db-ja.com

カスタムURLでテキストファイルを配信する方法

WebサーバのルートにWordPressサイトがインストールされています。/ここからテキストファイルを提供します。/.hiddendir/secondlevel/textfile

このファイルとディレクトリをサーバー上の../wwwroot/.hiddendir/secondlevel/textfileに作成しました

アクセスしようとすると、ワードプレスから404が返されます。

その理由は、私が使用したいサービスに必要な「確認」ファイルを追加することです。それはあなたがウェブサイトを所有していることを確認するためにURLを見ます(ヤフーとグーグルは彼らの様々なサービスのためにこれをします)。

テキストファイルをメディアギャラリーに追加しようとしましたが、URLはカスタマイズできません。プラグインを探していますが、見つけることができません。

add_rewrite_rule を使用して、http://example.com/api/files/xyzのような新しいエンドポイントを作成し、リクエストを処理してサーバーからのコンテンツをレンダリングすることができます。これにより、ファイルの出所を隠すことができますが、それでもその内容にアクセスできます。

add_rewrite_rule はあなたを必要とします flush_rewrite_rules しかしあなたはあなたがあなたの書き換えを変更する度に一度だけそれをする必要があります。そのため、基本的にその1行をテスト用に残しますが、製造中はそれを取り出します。

URLがファイルを要求していること、そしてどのファイルを表示したいのかが決まったら、 is_readable を素早く確認して、 file exists を確認し、コンテンツにアクセスできるようにします。

その時点で、ファイルを記述するためのヘッダをいくつか書いたり、内容を読んだり、 readfile を使って出力バッファに書き込むことができます。

テーマに関係なくアクセスを許可するには、これをfunctions.phpまたは plugin にドロップします。

説明はコードのコメントにあります。

<?php

if ( ! class_exists( 'FileEndpoint' ) ):

    class FileEndpoint {
        const ENDPOINT_QUERY_NAME  = 'api/files';
        const ENDPOINT_QUERY_PARAM = '__api_files';

        // WordPress hooks

        public function init() {
            add_filter( 'query_vars', array ( $this, 'add_query_vars' ), 0 );
            add_action( 'parse_request', array ( $this, 'sniff_requests' ), 0 );
            add_action( 'init', array ( $this, 'add_endpoint' ), 0 );
        }

        // Add public query vars

        public function add_query_vars( $vars ) {

            // add all the things we know we'll use

            $vars[] = static::ENDPOINT_QUERY_PARAM;
            $vars[] = 'file';

            return $vars;
        }

        // Add API Endpoint

        public function add_endpoint() {
            add_rewrite_rule( '^' . static::ENDPOINT_QUERY_NAME . '/([^/]*)/?', 'index.php?' . static::ENDPOINT_QUERY_PARAM . '=1&file=$matches[1]', 'top' );

            //////////////////////////////////
            flush_rewrite_rules( false ); //// <---------- REMOVE THIS WHEN DONE
            //////////////////////////////////
        }

        // Sniff Requests

        public function sniff_requests( $wp_query ) {
            global $wp;

            if ( isset(
                $wp->query_vars[ static::ENDPOINT_QUERY_PARAM ],
                $wp->query_vars[ 'file' ] ) ) {
                $this->handle_file_request(); // handle it
            }
        }

        // Handle Requests

        protected function handle_file_request() {
            global $wp;

            $file     = $wp->query_vars[ 'file' ];
            $filepath = '';

            switch ( $file ) {

                // example.com/api/files/xyz
                case 'xyz':
                    $filepath = __DIR__ . '/filename.txt';
                    break;
            }

            if ( ! empty( $filepath ) ) {

                // Make sure this is an accessible file
                // If we can't read it throw an Error
                if ( ! is_readable( $filepath ) ) {

                    $err = new WP_Error( "Forbidden", "Access is not allowed for this request.", 403 );
                    wp_die( $err->get_error_message(), $err->get_error_code() );
                }

                // We can read it, so let's render it
                $this->serve_file( $filepath );
            }

            // Nothing happened, just give some feedback
            $err = new WP_Error( "Bad Request", "Invalid Request.", 400 );
            wp_die( $err->get_error_message(), $err->get_error_code() );
        }

        // Output the file

        protected function serve_file( $filepath, $force_download = false ) {

            if ( ! empty ( $contents ) ) {

                // Write some headers

                header( "Cache-control: private" );
                if ( $force_download ) {

                    // Allow a forced download
                    header( "Content-type: application/force-download" );
                    header( "Content-disposition: attachment; filename=\"filename.txt\"" );
                }
                header( "Content-transfer-encoding: binary\n" );
                header( "Content-Length: " . filesize( $filepath ) );

                // render the contents of the file
                readfile( $filepath );

                // kill the request. Nothing else to do now.
                exit;
            }

            // nothing happened, :(
            return false;
        }
    }

    $wpFileEndpoint = new FileEndpoint();
    $wpFileEndpoint->init();

endif; // FileEndpoint
2
jgraup