1

複数のフィードからの最後のいくつかのツイートを表示するカスタムTwitterウィジェットを作成しようとしています。各フィードは、次のクラスのインスタンスを作成します。

<?php

class Foo{
  protected $name = '';

  //opts
  protected $numTweets = 3;
  protected $transName = ''; // Name of value in database.
  protected $backupName = '';
  protected $cacheTime = 5; // Time in minutes between updates.
  protected $exclude_replies = true; // Leave out @replies?

  public function __construct( $username ){
    $this->name = $username;
    $this->transName = 'jctft3' . $username;
    $this->backupName = 'jctfb3' . $username;
  }

  public function get_feed(){
    $feed = get_transient( $this->transName );

    // Do we already have saved tweet data? If not, lets get it.
    if( $feed === false  ){
      $feed = $this->call_twitter();
    }

    $html = $this->build_html( $feed );

    return $html;
  }// protected function get_feed(){...}

  protected function call_twitter(){
    /* We need the following:

    $feed = array(
      'username' => '',
      'friendly_name' => '',
      'url' => ''

      'tweets' => array(
        array(
          'html' => '',
          'url' => '',
          'time' => ''
        ),
        array(
          'html' => '',
          'url' => '',
          'time' => ''
        )
      )
    );
    */
    $feed = array();

    // Get the tweets from Twitter.
    $response = wp_remote_get( "http://api.twitter.com/1/statuses/user_timeline.json?screen_name={$this->name}&count=10&exclude_replies=false" );

    // parse Twitter response into an array
    if( !is_wp_error($response) && $response[ 'response' ][ 'code' ] == 200 ){
      // Get tweets into an array.
      $tweets_json = json_decode( $response['body'], true );
      // Now update the array to store just what we need.
      $feed[ 'username' ] = $tweets_json[ 0 ][ 'user' ][ 'screen_name' ];
      $feed[ 'friendly_name' ] = $tweets_json[ 0 ][ 'user' ][ 'name' ];
      $feed[ 'url' ] = 'https://twitter.com/' . $tweets_json[ 0 ][ 'user' ][ 'screen_name' ];
      $feed[ 'tweets' ] = array();

      foreach ( $tweets_json as $tweet ){
        $my_tweet = array();

        // Core info.
        $my_tweet[ 'url' ] = 'http://twitter.com/#!/'. $feed[ 'username' ] .'/status/'. $tweet['id_str'];
        // Message. Convert links to real links.
        $pattern = '/http:(\S)+/';
        $replace = '<a href="${0}" target="_blank" rel="nofollow">${0}</a>';
        $my_tweet[ 'html' ] = preg_replace( $pattern, $replace, $tweet['text'] );
        //$my_tweet[ 'html' ] = $tweet['text'];
        // Need to get time in Unix format.
        $time = $this->twitter_time( $tweet[ 'created_at' ] );
        //$time = date_parse( $time );
        //$uTime = mktime($time['hour'], $time['minute'], $time['second'], $time['month'], $time['day'], $time['year']);
        $my_tweet[ 'time' ] = $time;

        array_push( $feed[ 'tweets' ], $my_tweet );
      }

      // Save our new transient, and update the backup.
      set_transient( $this->transName, $feed, 60 * $this->cacheTime );
      update_option( $this->backupName, $feed );
    }
    else{
      // i.e. Fetching new tweets failed.
      $feed = get_option( $this->backupName ); // False if there has never been data saved.
    }

    return $feed;
  }

  protected function build_html( $feed ){
    $html = '';

    $is_top = false;
    if( $feed[ 'friendly_name' ] == 'Johnny Cupcakes' ){
      $is_top = true;
    }

    ob_start();
    include(  plugin_dir_path( __FILE__ ) . '../html/feed.html' );
    $html = ob_get_clean();

    return $html;
  }

}

?>

プラグインが初めてhtmlをビルドするとき(つまり、データがローカルデータベースに保存されているデータからではなくTwitterから直接プルされているとき)、すべてが正常に表示されます。ただし、get_transient()を使用してキャッシュされたデータを取得すると、一部のツイート(どのツイートがこのエラーを生成し、機能を拒否するツイートの数が異なります)で次のエラーが発生します。

Warning:  Illegal string offset 'username' in /Applications/MAMP/htdocs/sites/wp-johnnycupcakes/wp-content/plugins/jc-twitter-widget/html/feed.html on line 12

feed.htmlの12行目は次のとおりです。

<h3><a target="_new" href="<?php echo $feed[ 'url' ]; ?>"> @<?php echo $feed[ 'username' ]; ?> </a></h3>

さらに調査すると、一部のフィードでは、get_transient()を使用すると、返される値が配列ではなく、エンコードされた文字列(データベースにtransient_valuesを格納するためのWordpressのエンコード規則であると想定しています)のように見えることがあります。 )。文字列は次のようになります。

string(830) "a:4:{s:8:"username";s:15:"JHNYCPKS_London";s:13:"friendly_name";s:18:"Johnny Cupcakes UK";s:3:"url";s:35:"https://twitter.com/JHNYCPKS_London";s:6:"tweets";a:9:{i:0;a:3:{s:3:"url";s:63:"http://twitter.com/#!/JHNYCPKS_London/status/278196905350164480";s:4:"html";s:128:"Baked in USA long sleeve, Truffle and White Mens Basic Tee's are now back in stock come and grab them now while supplies last!!!";s:4:"time";s:11:"2 hours ago";}i:1;a:3:{s:3:"url";s:63:"http://twitter.com/#!/JHNYCPKS_London/status/278180246967173121";s:4:"html";s:121:"Put a pin on it! @ Johnny Cupcakes http://t.co/nxVSAG63";s:4:"time";s:11:"4 hours ago";}i:2;a:3:{s:3:"url";s:63:"http://twitter.com/#!/JHNYCPKS_London/status/278179975474053120";s:4:"html";s:161:"Big kid magnet came in today! "

配列が返されると(したがって、フィードが正常に表示される)、次のようになります。

array(4) {
  ["username"]=>
  string(15) "JHNYCPKS_Boston"
  ["friendly_name"]=>
  string(20) "JohnnyCupcakesBoston"
  ["url"]=>
  string(35) "https://twitter.com/JHNYCPKS_Boston"
  ["tweets"]=>
  array(7) {
    [0]=>
    array(3) {
      ["url"]=>
      string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/278204808756862976"
      ["html"]=>
      string(139) "IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING!"
      ["time"]=>
      string(11) "2 hours ago"
    }
    [1]=>
    array(3) {
      ["url"]=>
      string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/278169219160489984"
      ["html"]=>
      string(167) "Four #freshlybaked keychains were released this weekend! Which is your favorite? <a href="http://t.co/Xn16NsjU" target="_blank" rel="nofollow">http://t.co/Xn16NsjU</a>"
      ["time"]=>
      string(11) "4 hours ago"
    }
    [2]=>
    array(3) {
      ["url"]=>
      string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/278137791391617025"
      ["html"]=>
      string(29) "@thatkidTHILL good luck, man!"
      ["time"]=>
      string(11) "6 hours ago"
    }
    [3]=>
    array(3) {
      ["url"]=>
      string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/278137703281881088"
      ["html"]=>
      string(96) "@dcachopa18 i don't think so, sorry! we'll let you know if we do. what size are you looking for?"
      ["time"]=>
      string(11) "6 hours ago"
    }
    [4]=>
    array(3) {
      ["url"]=>
      string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/277888036237373440"
      ["html"]=>
      string(188) "Only a few hours left! Spend $50, get a $10 gift card. Stop in or shop online. We close at 7 tonight! <a href="http://t.co/082T5jTf" target="_blank" rel="nofollow">http://t.co/082T5jTf</a>"
      ["time"]=>
      string(12) "23 hours ago"
    }
    [5]=>
    array(3) {
      ["url"]=>
      string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/277786268274933760"
      ["html"]=>
      string(135) "Here's the new Boston in-store! cc: @b3asTTw33ts <a href="http://t.co/soLoEYqv" target="_blank" rel="nofollow">http://t.co/soLoEYqv</a>"
      ["time"]=>
      string(9) "yesterday"
    }
    [6]=>
    array(3) {
      ["url"]=>
      string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/277526406076968961"
      ["html"]=>
      string(119) "What's everyone's favorite piece from this release?! The new Boston exclusive seems to be the hot ticket. #freshlybaked"
      ["time"]=>
      string(9) "yesterday"
    }
  }
}

私はこれを引き起こしている可能性があるものについていくつかのアイデアを持っています:

  • 一時的なデータに大量のデータを保存しようとしています
  • 引き込まれている一部の文字は、Wordpressがデータを文字列に変換する方法またはその逆の方法を台無しにしています。

誰かがこの問題についてある程度の経験があり、それを修正するための正しい方向に私を向けることができますか?

4

1 に答える 1

5

アレイのシリアル化で問題が発生しています。表示されているサンプルのエンコードされた文字列は、配列の部分的なシリアル化にすぎないため、どこかで(シリアル化またはDBへの保存のいずれかで)スリップアップしています。

たぶん、自分でシリアル化して(serialize()を呼び出し)、base64でエンコードしてから、トランジェントを設定してみてください。取得時に、base64-decode、およびdeserialise。WordPress / wpdbがシリアル化された配列を保存することに問題がある場合は、うまくいく可能性があります。

于 2012-12-10T23:06:36.270 に答える