web-dev-qa-db-ja.com

Wordpressのテンプレートでパスワード保護された外部RSSを表示する

私は私のワードプレスのブログページのテンプレートで外部のRSSフィードを表示するために以下のコードを使用しています。

<?php 
  include_once(ABSPATH . WPINC . '/rss.php');
  $rss = fetch_rss('http://feeds.feedburner.com/site-feed');
  $maxitems = 10;
  $items = array_slice($rss->items, 0, $maxitems);
?>
<ul class="arrow">
  <?php if (empty($items)): ?>
    <li>No items</li>
  <?php else:
      foreach ( $items as $item ):
        ?>
        <li>
          <a href='<?php echo $item['link']; ?>' title='<?php echo $item['title']; ?>'>
            <?php echo $item['title']; ?>
          </a>
        </li>
        <?php
      endforeach;
    endif;
  ?>

上記のフィードは以前オープンしていましたが、現在はパスワードで保護されています。私はすでにユーザー名とパスワードを知っています。ユーザー/名前パスワードを使用するために上記のコードを微調整するにはどうすればいいですか?

1
Skotlive

HTTP認証 を使って外部フィードを取得するという意味です。

HTTP認証を使ったフィードの取得

fetch_rss() MagPie ライブラリを使うことに注意してください。これはWordPressでは非推奨です。

代わりに SimplePie ライブラリを使用するfetch_feed()を使用してください。

それはこの種類のURLをサポートしていないけれどもそれは見えます:

http://user:[email protected]/feed/

コマンドラインでcurlと一緒に使うことができるように、例えば:

# curl -i http://user:[email protected]/feed/

fetch_feed()関数は、フィードを取得するためにwp_safe_remote_request()関数を呼び出します。これはWP_SimplePie_Fileクラスで起こります。これはSimplePie_Fileクラスの拡張です。

これは良いニュースです。なぜなら、リクエストヘッダを修正するためにhttp_request_argsフィルタを使用できるからです。 HTTP API のCodexページをチェックアウトすると、外部参照でJohn Blackbournの短くて有益な投稿へのリンクがあることがわかります。 WordPress HTTP APIを使った基本認証 。そこで彼は次の例を挙げています:

$args = array(
    'headers' => array(
        'Authorization' => 'Basic ' . base64_encode( YOUR_USERNAME . ':' . YOUR_PASSWORD )
    )
);
wp_remote_request( $url, $args );

要求と共に正しい認証ヘッダーを送信します。

デモプラグイン

次のURLタイプのサポートを追加できます。

$rss = fetch_feed( 'http://user:[email protected]/feed/' );

このデモプラグインでは:

<?php
/**
 * Plugin Name: Fetch Feeds with http authentication
 * Description: Allows feeds urls like http://user:[email protected]/feed/
 * Plugin URI:  http://wordpress.stackexchange.com/a/199101/26350
 */    
add_action( 'wp_feed_options', function( $feed, $url )
{
    $user = parse_url( $feed->feed_url, PHP_URL_USER );
    $pass = parse_url( $feed->feed_url, PHP_URL_PASS );

    // Nothing to do
    if( ! $user || ! $pass )
        return;

    // Remove the user:pass@ part from the feed url
    $feed->feed_url = str_replace( 
        sprintf( '%s:%s@', $user, $pass ), 
        '', 
        $feed->feed_url
    );

    add_filter( 'http_request_args', function( $r, $url ) use ( $user, $pass )
    {
        // Add the user & pass to the request's header
        if( $user && $pass )
            $r['headers']['Authorization'] = 'Basic ' . base64_encode(  $user . ':' . $pass );
        return $r;
    }, 10, 2 );     

}, 10, 2 );

更新:

これはエラーがどのように見えるかです:

WP HTTP Error: A valid URL was not provided.

実行すると:

$rss = fetch_feed( 'http://user:[email protected]/feed/' );

これは WP_Http::request()メソッド からきています。

if ( empty( $url ) || empty( $arrURL['scheme'] ) )
    return new WP_Error('http_request_failed', __('A valid URL was not provided.'));

これがwp_safe_remote_request()関数が どのように定義されているかです

function wp_safe_remote_request( $url, $args = array() ) {
        $args['reject_unsafe_urls'] = true;
        $http = _wp_http_get_object();
        return $http->request( $url, $args );
}

私はそれで遊んでいてテストしました:

$args['reject_unsafe_urls'] = false;

スルー:

add_action( 'wp_feed_options', function( $feed )
{
    $user = parse_url( $feed->feed_url, PHP_URL_USER );
    $pass = parse_url( $feed->feed_url, PHP_URL_PASS );

    if( ! $user || ! $pass )
        return;

    add_filter( 'http_request_args', function( $r, $url ) use ( $user, $pass )
    {
        if( $user && $pass )
            $r['reject_unsafe_urls'] = false;
        return $r;
    }, 10, 2 );     
} );

そしてこれはうまくいった:

$rss = fetch_feed( 'http://user:[email protected]/feed/' );

WP_Http::request()メソッドの内部では、次の条件がありました。

if ( $r['reject_unsafe_urls'] )
    $url = wp_http_validate_url( $url );

wp_http_validate_url()はこのURLを検証していないようです。

http://user:[email protected]/feed/

reject_unsafe_urlsをfalseに設定することで、そのチェックをスキップします。

これには実際に利用可能なフィルタがあります:http_request_reject_unsafe_urls、しかし私は使うことをお勧めしません:

add_filter( `http_request_reject_unsafe_urls`, '__return_false' );

私は上記のデモプラグインは、一般的にはより良い選択であると思います。なぜなら、それは認証ストリップURLのwp_http_validate_url()をまだ使用しているからです。

注意:

この部分

if ( isset( $parsed_url['user'] ) || isset( $parsed_url['pass'] ) )
    return false;

wp_http_validate_url()関数内では、 show:stop のような user:pass のURLのfetch_feed()が表示されます。

2
birgire