SitePoint Sponsor

User Tag List

Results 1 to 23 of 23
  1. #1
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Need help pointing Javascript XML to PHP file for Twitter 1.1 API

    Hi guys,

    I noticed that my clients' Twitter feeds aren't working the other day and, after a bit of research, it turns out that Twitter require access tokens now to use their API.

    I've seen this tutorial (http://www.fullondesign.co.uk/coding...riptjquery.htm) and have sorted the PHP file with my access tokens etc.

    However, I need help pointing to the PHP file. I can't find the relevant code anywhere in my Javascript XML file. I assume it needs to be brought in another way.

    Here is my Javascript XLM file - can anyone see how I can point it to twitter-proxy.php?

    Code:
    (function($) {
    
      $.fn.tweet = function(o){
        var s = $.extend({
          username: ["My_Client"],                // [string]   required, unless you want to display our tweets. :) it can be an array, just do ["username1","username2","etc"]
          list: null,                               // [string]   optional name of list belonging to username
          avatar_size: null,                        // [integer]  height and width of avatar if displayed (48px max)
          count: 5,                                 // [integer]  how many tweets to display?
          intro_text: null,                         // [string]   do you want text BEFORE your your tweets?
          outro_text: null,                         // [string]   do you want text AFTER your tweets?
          join_text:  null,                         // [string]   optional text in between date and tweet, try setting to "auto"
          auto_join_text_default: "",        // [string]   auto text for non verb: "i said" bullocks
          auto_join_text_ed: "",                   // [string]   auto text for past tense: "i" surfed
          auto_join_text_ing: "",               // [string]   auto tense for present tense: "i was" surfing
          auto_join_text_reply: "",     // [string]   auto tense for replies: "i replied to" @someone "with"
          auto_join_text_url: "",   // [string]   auto tense for urls: "i was looking at" http:...
          loading_text: null,                       // [string]   optional loading text, displayed while tweets load
          query: null,                              // [string]   optional search query
          refresh_interval: null ,                  // [integer]  optional number of seconds after which to reload tweets
          twitter_url: "twitter.com",               // [string]   custom twitter url, if any (apigee, etc.)
          twitter_api_url: "api.twitter.com",       // [string]   custom twitter api url, if any (apigee, etc.)
          twitter_search_url: "search.twitter.com", // [string]   custom twitter search url, if any (apigee, etc.)
          template: function(info) {                // [function] template used to construct each tweet <li>
            return info["avatar"] + info["time"] + info["join"] + info["text"];
          }
        }, o);
    
        $.fn.extend({
          linkUrl: function() {
            var returning = [];
            // See http://daringfireball.net/2010/07/improved_regex_for_matching_urls
            var regexp = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?]))/gi;
            this.each(function() {
              returning.push(this.replace(regexp,
                                          function(match) {
                                            var url = (/^[a-z]+:/i).test(match) ? match : "http://"+match;
                                            return "<a href=\""+url+"\">"+match+"</a>";
                                          }));
            });
            return $(returning);
          },
          linkUser: function() {
            var returning = [];
            var regexp = /[\@]+([A-Za-z0-9-_]+)/gi;
            this.each(function() {
              returning.push(this.replace(regexp,"<a href=\"http://"+s.twitter_url+"/$1\">@$1</a>"));        });
            return $(returning);
          },
          linkHash: function() {
            var returning = [];
            var regexp = /(?:^| )[\#]+([A-Za-z0-9-_]+)/gi;
            this.each(function() {
              returning.push(this.replace(regexp, ' <a href="http://'+s.twitter_search_url+'/search?q=&tag=$1&lang=all&from='+s.username.join("%2BOR%2B")+'" target="_blank">#$1</a>'));
            });
            return $(returning);
          },
          capAwesome: function() {
            var returning = [];
            this.each(function() {
              returning.push(this.replace(/\b(awesome)\b/gi, '<span class="awesome">$1</span>'));
            });
            return $(returning);
          },
          capEpic: function() {
            var returning = [];
            this.each(function() {
              returning.push(this.replace(/\b(epic)\b/gi, '<span class="epic">$1</span>'));
            });
            return $(returning);
          },
          makeHeart: function() {
            var returning = [];
            this.each(function() {
              returning.push(this.replace(/(&lt;)+[3]/gi, "<tt class='heart'>&#x2665;</tt>"));
            });
            return $(returning);
          }
        });
    
        function parse_date(date_str) {
          // The non-search twitter APIs return inconsistently-formatted dates, which Date.parse
          // cannot handle in IE. We therefore perform the following transformation:
          // "Wed Apr 29 08:53:31 +0000 2009" => "Wed, Apr 29 2009 08:53:31 +0000"
          return Date.parse(date_str.replace(/^([a-z]{3})( [a-z]{3} \d\d?)(.*)( \d{4})$/i, '$1,$2$4$3'));
        }
    
        function relative_time(time_value) {
          var parsed_date = parse_date(time_value);
          var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
          var delta = parseInt((relative_to.getTime() - parsed_date) / 1000, 10);
          var r = '';
          if (delta < 60) {
            r = delta + ' seconds ago';
          } else if(delta < 120) {
            r = 'a minute ago';
          } else if(delta < (45*60)) {
            r = (parseInt(delta / 60, 10)).toString() + ' minutes ago';
          } else if(delta < (2*60*60)) {
            r = 'an hour ago';
          } else if(delta < (24*60*60)) {
            r = '' + (parseInt(delta / 3600, 10)).toString() + ' hours ago';
          } else if(delta < (48*60*60)) {
            r = 'a day ago';
          } else {
            r = (parseInt(delta / 86400, 10)).toString() + ' days ago';
          }
          return 'about ' + r;
        }
    
        function build_url() {
          var proto = ('https:' == document.location.protocol ? 'https:' : 'http:');
          if (s.list) {
            return proto+"//"+s.twitter_api_url+"/1/"+s.username[0]+"/lists/"+s.list+"/statuses.json?per_page="+s.count+"&callback=?";
          } else if (s.query === null && s.username.length == 1) {
            return proto+'//'+s.twitter_api_url+'/1/statuses/user_timeline.json?screen_name='+s.username[0]+'&count='+s.count+'&include_rts=1&callback=?';
          } else {
            var query = (s.query || 'from:'+s.username.join(' OR from:'));
            return proto+'//'+s.twitter_search_url+'/search.json?&q='+encodeURIComponent(query)+'&rpp='+s.count+'&callback=?';
          }
        }
    
        return this.each(function(i, widget){
          var list = $('<ul class="tweet_list">').appendTo(widget);
          var intro = '<p class="tweet_intro">'+s.intro_text+'</p>';
          var outro = '<p class="tweet_outro">'+s.outro_text+'</p>';
          var loading = $('<p class="loading">'+s.loading_text+'</p>');
    
          if(typeof(s.username) == "string"){
            s.username = [s.username];
          }
    
          if (s.loading_text) $(widget).append(loading);
          $(widget).bind("load", function(){
            $.getJSON(build_url(), function(data){
              if (s.loading_text) loading.remove();
              if (s.intro_text) list.before(intro);
              list.empty();
    
              var tweets = $.map(data.results || data, function(item){
                var join_text = s.join_text;
    
                // auto join text based on verb tense and content
                if (s.join_text == "auto") {
                  if (item.text.match(/^(@([A-Za-z0-9-_]+)) .*/i)) {
                    join_text = s.auto_join_text_reply;
                  } else if (item.text.match(/(^\w+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+) .*/i)) {
                    join_text = s.auto_join_text_url;
                  } else if (item.text.match(/^((\w+ed)|just) .*/im)) {
                    join_text = s.auto_join_text_ed;
                  } else if (item.text.match(/^(\w*ing) .*/i)) {
                    join_text = s.auto_join_text_ing;
                  } else {
                    join_text = s.auto_join_text_default;
                  }
                }
    
                // Basic building blocks for constructing tweet <li> using a template
                var screen_name = item.from_user || item.user.screen_name;
                var source = item.source;
                var user_url = "http://"+s.twitter_url+"/"+screen_name;
                var avatar_size = s.avatar_size;
                var avatar_url = item.profile_image_url || item.user.profile_image_url;
                var tweet_url = "http://"+s.twitter_url+"/"+screen_name+"/statuses/"+item.id_str;
                var tweet_time = item.created_at;
                var tweet_relative_time = relative_time(tweet_time);
                var tweet_raw_text = item.text;
                var tweet_text = $([tweet_raw_text]).linkUrl().linkUser().linkHash()[0];
    
                // Default spans, and pre-formatted blocks for common layouts
                var user = '<a target="_blank" class="tweet_user" href='+user_url+'">'+screen_name+'</a>';
                var join = ((s.join_text) ? ('<span class="tweet_join"> '+join_text+' </span>') : ' ');
                var avatar = (avatar_size ?
                              ('<a  target="_blank" class="tweet_avatar" href="'+user_url+'"><img src="'+avatar_url+
                               '" height="'+avatar_size+'" width="'+avatar_size+
                               '" alt="'+screen_name+'\'s avatar" title="'+screen_name+'\'s avatar" border="0"/></a>') : '');
                var time = '<span class="tweet_time"><a href="'+tweet_url+'" title="view tweet on twitter" target="_blank">'+tweet_relative_time+'</a></span><br />';
                var text = '<span class="tweet_text">'+$([tweet_text]).makeHeart().capAwesome().capEpic()[0]+ '</span>';
    
                return "<li>" +
                            s.template({
                              item: item, // For advanced users who want to dig out other info
                              screen_name: screen_name,
                              user_url: user_url,
                              avatar_size: avatar_size,
                              avatar_url: avatar_url,
                              source: source,
                              tweet_url: tweet_url,
                              tweet_time: tweet_time,
                              tweet_relative_time: tweet_relative_time,
                              tweet_raw_text: tweet_raw_text,
                              tweet_text: tweet_text,
                              user: user,
                              join: join,
                              avatar: avatar,
                              time: time,
                              text: text
                           }) +
                        "</li>";
              });
    
              list.append(tweets.join('')).
                  children('li:first').addClass('tweet_first').end().
                  children('li:odd').addClass('tweet_even').end().
                  children('li:even').addClass('tweet_odd');
    
              if (s.outro_text) list.after(outro);
              $(widget).trigger("loaded").trigger((tweets.length === 0 ? "empty" : "full"));
              if (s.refresh_interval) {
                window.setTimeout(function() { $(widget).trigger("load"); }, 1000 * s.refresh_interval);
              }
            });
          }).trigger("load");
        });
      };
    })(jQuery);
    Thank you very much and I hope to hear from you!

    SM

  2. #2
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,407
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    Hi,

    You need to make a couple of small changes, here:
    Code JavaScript:
    twitter_api_url: "/twitter-proxy.php?url=",  // Change the path if your php file is in a different location

    and here:
    Code JavaScript:
    function build_url() {
      var proto = ('https:' == document.location.protocol ? 'https:' : 'http:');
      if (s.list) {
        return s.twitter_api_url+encodeURIComponent(s.username[0]+"/lists/"+s.list+"/statuses.json?per_page="+s.count+"&callback=?");  // This line changed
      } else if (s.query === null && s.username.length == 1) {
        return s.twitter_api_url+encodeURIComponent('statuses/user_timeline.json?screen_name='+s.username[0]+'&count='+s.count+'&include_rts=1&callback=?');  // And this one
      } else {
        var query = (s.query || 'from:'+s.username.join(' OR from:'));
        return proto+'//'+s.twitter_search_url+'/search.json?&q='+encodeURIComponent(query)+'&rpp='+s.count+'&callback=?';
      }
    }

    Note that I've not changed the search url, as it doesn't seem to be supported in the PHP script you're using. You also need to make sure that you add all the twitter urls (inc query strings) that you intend to use are included on the whitelist in the PHP script.

  3. #3
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hey Fretburner!

    Thank you for the suggestion! Unfortunately it didn't seem to work though - I still just get 'Loading Tweets...' when I test the page.

    When I view twitter-proxy.php it says 'No URL set'.

    Is there something I am missing?

    My code now looks like:

    Code:
    (function($) {
    
      $.fn.tweet = function(o){
        var s = $.extend({
          username: ["My_Client"],                // [string]   required, unless you want to display our tweets. :) it can be an array, just do ["username1","username2","etc"]
          list: null,                               // [string]   optional name of list belonging to username
          avatar_size: null,                        // [integer]  height and width of avatar if displayed (48px max)
          count: 5,                                 // [integer]  how many tweets to display?
          intro_text: null,                         // [string]   do you want text BEFORE your your tweets?
          outro_text: null,                         // [string]   do you want text AFTER your tweets?
          join_text:  null,                         // [string]   optional text in between date and tweet, try setting to "auto"
          auto_join_text_default: "",        // [string]   auto text for non verb: "i said" bullocks
          auto_join_text_ed: "",                   // [string]   auto text for past tense: "i" surfed
          auto_join_text_ing: "",               // [string]   auto tense for present tense: "i was" surfing
          auto_join_text_reply: "",     // [string]   auto tense for replies: "i replied to" @someone "with"
          auto_join_text_url: "",   // [string]   auto tense for urls: "i was looking at" http:...
          loading_text: null,                       // [string]   optional loading text, displayed while tweets load
          query: null,                              // [string]   optional search query
          refresh_interval: null ,                  // [integer]  optional number of seconds after which to reload tweets
          twitter_url: "twitter.com",               // [string]   custom twitter url, if any (apigee, etc.)
          twitter_api_url: "assets/scripts/tweets/twitter-proxy.php?url=",  // Change the path if your php file is in a different location
          twitter_search_url: "search.twitter.com", // [string]   custom twitter search url, if any (apigee, etc.)
          template: function(info) {                // [function] template used to construct each tweet <li>
            return info["avatar"] + info["time"] + info["join"] + info["text"];
          }
        }, o);
    
        $.fn.extend({
          linkUrl: function() {
            var returning = [];
            // See http://daringfireball.net/2010/07/improved_regex_for_matching_urls
            var regexp = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?“”‘’]))/gi;
            this.each(function() {
              returning.push(this.replace(regexp,
                                          function(match) {
                                            var url = (/^[a-z]+:/i).test(match) ? match : "http://"+match;
                                            return "<a href=\""+url+"\">"+match+"</a>";
                                          }));
            });
            return $(returning);
          },
          linkUser: function() {
            var returning = [];
            var regexp = /[\@]+([A-Za-z0-9-_]+)/gi;
            this.each(function() {
              returning.push(this.replace(regexp,"<a href=\"http://"+s.twitter_url+"/$1\">@$1</a>"));        });
            return $(returning);
          },
          linkHash: function() {
            var returning = [];
            var regexp = /(?:^| )[\#]+([A-Za-z0-9-_]+)/gi;
            this.each(function() {
              returning.push(this.replace(regexp, ' <a href="http://'+s.twitter_search_url+'/search?q=&tag=$1&lang=all&from='+s.username.join("%2BOR%2B")+'" target="_blank">#$1</a>'));
            });
            return $(returning);
          },
          capAwesome: function() {
            var returning = [];
            this.each(function() {
              returning.push(this.replace(/\b(awesome)\b/gi, '<span class="awesome">$1</span>'));
            });
            return $(returning);
          },
          capEpic: function() {
            var returning = [];
            this.each(function() {
              returning.push(this.replace(/\b(epic)\b/gi, '<span class="epic">$1</span>'));
            });
            return $(returning);
          },
          makeHeart: function() {
            var returning = [];
            this.each(function() {
              returning.push(this.replace(/(&lt;)+[3]/gi, "<tt class='heart'>&#x2665;</tt>"));
            });
            return $(returning);
          }
        });
    
        function parse_date(date_str) {
          // The non-search twitter APIs return inconsistently-formatted dates, which Date.parse
          // cannot handle in IE. We therefore perform the following transformation:
          // "Wed Apr 29 08:53:31 +0000 2009" => "Wed, Apr 29 2009 08:53:31 +0000"
          return Date.parse(date_str.replace(/^([a-z]{3})( [a-z]{3} \d\d?)(.*)( \d{4})$/i, '$1,$2$4$3'));
        }
    
        function relative_time(time_value) {
          var parsed_date = parse_date(time_value);
          var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
          var delta = parseInt((relative_to.getTime() - parsed_date) / 1000, 10);
          var r = '';
          if (delta < 60) {
            r = delta + ' seconds ago';
          } else if(delta < 120) {
            r = 'a minute ago';
          } else if(delta < (45*60)) {
            r = (parseInt(delta / 60, 10)).toString() + ' minutes ago';
          } else if(delta < (2*60*60)) {
            r = 'an hour ago';
          } else if(delta < (24*60*60)) {
            r = '' + (parseInt(delta / 3600, 10)).toString() + ' hours ago';
          } else if(delta < (48*60*60)) {
            r = 'a day ago';
          } else {
            r = (parseInt(delta / 86400, 10)).toString() + ' days ago';
          }
          return 'about ' + r;
        }
    
    
    function build_url() {
      var proto = ('https:' == document.location.protocol ? 'https:' : 'http:');
      if (s.list) {
        return s.twitter_api_url+encodeURIComponent(s.username[0]+"/lists/"+s.list+"/statuses.json?per_page="+s.count+"&callback=?");  // This line changed
      } else if (s.query === null && s.username.length == 1) {
        return s.twitter_api_url+encodeURIComponent('statuses/user_timeline.json?screen_name='+s.username[0]+'&count='+s.count+'&include_rts=1&callback=?');  // And this one
      } else {
        var query = (s.query || 'from:'+s.username.join(' OR from:'));
        return proto+'//'+s.twitter_search_url+'/search.json?&q='+encodeURIComponent(query)+'&rpp='+s.count+'&callback=?';
      }
    }
    
    
    
        return this.each(function(i, widget){
          var list = $('<ul class="tweet_list">').appendTo(widget);
          var intro = '<p class="tweet_intro">'+s.intro_text+'</p>';
          var outro = '<p class="tweet_outro">'+s.outro_text+'</p>';
          var loading = $('<p class="loading">'+s.loading_text+'</p>');
    
          if(typeof(s.username) == "string"){
            s.username = [s.username];
          }
    
          if (s.loading_text) $(widget).append(loading);
          $(widget).bind("load", function(){
            $.getJSON(build_url(), function(data){
              if (s.loading_text) loading.remove();
              if (s.intro_text) list.before(intro);
              list.empty();
    
              var tweets = $.map(data.results || data, function(item){
                var join_text = s.join_text;
    
                // auto join text based on verb tense and content
                if (s.join_text == "auto") {
                  if (item.text.match(/^(@([A-Za-z0-9-_]+)) .*/i)) {
                    join_text = s.auto_join_text_reply;
                  } else if (item.text.match(/(^\w+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+) .*/i)) {
                    join_text = s.auto_join_text_url;
                  } else if (item.text.match(/^((\w+ed)|just) .*/im)) {
                    join_text = s.auto_join_text_ed;
                  } else if (item.text.match(/^(\w*ing) .*/i)) {
                    join_text = s.auto_join_text_ing;
                  } else {
                    join_text = s.auto_join_text_default;
                  }
                }
    
                // Basic building blocks for constructing tweet <li> using a template
                var screen_name = item.from_user || item.user.screen_name;
                var source = item.source;
                var user_url = "http://"+s.twitter_url+"/"+screen_name;
                var avatar_size = s.avatar_size;
                var avatar_url = item.profile_image_url || item.user.profile_image_url;
                var tweet_url = "http://"+s.twitter_url+"/"+screen_name+"/statuses/"+item.id_str;
                var tweet_time = item.created_at;
                var tweet_relative_time = relative_time(tweet_time);
                var tweet_raw_text = item.text;
                var tweet_text = $([tweet_raw_text]).linkUrl().linkUser().linkHash()[0];
    
                // Default spans, and pre-formatted blocks for common layouts
                var user = '<a target="_blank" class="tweet_user" href='+user_url+'">'+screen_name+'</a>';
                var join = ((s.join_text) ? ('<span class="tweet_join"> '+join_text+' </span>') : ' ');
                var avatar = (avatar_size ?
                              ('<a  target="_blank" class="tweet_avatar" href="'+user_url+'"><img src="'+avatar_url+
                               '" height="'+avatar_size+'" width="'+avatar_size+
                               '" alt="'+screen_name+'\'s avatar" title="'+screen_name+'\'s avatar" border="0"/></a>') : '');
                var time = '<span class="tweet_time"><a href="'+tweet_url+'" title="view tweet on twitter" target="_blank">'+tweet_relative_time+'</a></span><br />';
                var text = '<span class="tweet_text">'+$([tweet_text]).makeHeart().capAwesome().capEpic()[0]+ '</span>';
    
                return "<li>" +
                            s.template({
                              item: item, // For advanced users who want to dig out other info
                              screen_name: screen_name,
                              user_url: user_url,
                              avatar_size: avatar_size,
                              avatar_url: avatar_url,
                              source: source,
                              tweet_url: tweet_url,
                              tweet_time: tweet_time,
                              tweet_relative_time: tweet_relative_time,
                              tweet_raw_text: tweet_raw_text,
                              tweet_text: tweet_text,
                              user: user,
                              join: join,
                              avatar: avatar,
                              time: time,
                              text: text
                           }) +
                        "</li>";
              });
    
              list.append(tweets.join('')).
                  children('li:first').addClass('tweet_first').end().
                  children('li:odd').addClass('tweet_even').end().
                  children('li:even').addClass('tweet_odd');
    
              if (s.outro_text) list.after(outro);
              $(widget).trigger("loaded").trigger((tweets.length === 0 ? "empty" : "full"));
              if (s.refresh_interval) {
                window.setTimeout(function() { $(widget).trigger("load"); }, 1000 * s.refresh_interval);
              }
            });
          }).trigger("load");
        });
      };
    })(jQuery);

    Thank you for all your help

  4. #4
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,407
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    Is the page online somewhere that you could link to? Or if not, could you post the code for the whole page?

  5. #5
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yeah sure, sorry - the link is here.

    Thank you, much appreciated!

  6. #6
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,407
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    The server is returning 'URL is not authorised', so it seems that your PHP script couldn't find the URL in the whitelist. According to the article you linked to, you need to set the whitelist like this:
    PHP Code:
    $whitelist = array(
        
    'statuses/user_timeline.json?screen_name=Max_Fewtrell&count=5&include_rts=1&callback=?'=>true
    ); 

  7. #7
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you for the reply.

    I'm afraid I still can't get it to work - I'm sure it's me missing something! This is what my PHP looks like:

    Code:
    <?php
    
    /**
     *  Usage:
     *  Send the url you want to access url encoded in the url paramater, for example (This is with JS): 
     *  /twitter-proxy.php?url='+encodeURIComponent('statuses/user_timeline.json?screen_name=MikeRogers0&count=2')
    */
    
    // The tokens, keys and secrets from the app you created at https://dev.twitter.com/apps
    $config = array(
    	'oauth_access_token' => '',
    	'oauth_access_token_secret' => '',
    	'consumer_key' => '',
    	'consumer_secret' => '',
    	'use_whitelist' => true, // If you want to only allow some requests to use this script.
    	'base_url' => 'http://api.twitter.com/1.1/'
    );
    
    // Only allow certain requests to twitter. Stop randoms using your server as a proxy.
    
    // WHITELIST
    $whitelist = array(
        'statuses/user_timeline.json?screen_name=Max_Fewtrell&count=5&include_rts=1&callback=?'=>true
    ); 
    
    /*
    * Ok, no more config should really be needed. Yay!
    */
    
    // We'll get the URL from $_GET[]. Make sure the url is url encoded, for example encodeURIComponent('statuses/user_timeline.json?screen_name=MikeRogers0&count=10&include_rts=false&exclude_replies=true')
    if(!isset($_GET['url'])){
    	die('No URL set');
    }
    
    $url = $_GET['url'];
    
    
    if($config['use_whitelist'] && !isset($whitelist[$url])){
    	die('URL is not authorised');
    }
    
    // Figure out the URL parmaters
    $url_parts = parse_url($url);
    parse_str($url_parts['query'], $url_arguments);
    
    $full_url = $config['base_url'].$url; // Url with the query on it.
    $base_url = $config['base_url'].$url_parts['path']; // Url without the query.
    
    /**
    * Code below from http://stackoverflow.com/questions/12916539/simplest-php-example-retrieving-user-timeline-with-twitter-api-version-1-1 by Rivers 
    * with a few modfications by Mike Rogers to support variables in the URL nicely
    */
    
    function buildBaseString($baseURI, $method, $params) {
    	$r = array();
    	ksort($params);
    	foreach($params as $key=>$value){
    	$r[] = "$key=" . rawurlencode($value);
    	}
    	return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
    }
    
    function buildAuthorizationHeader($oauth) {
    	$r = 'Authorization: OAuth ';
    	$values = array();
    	foreach($oauth as $key=>$value)
    	$values[] = "$key=\"" . rawurlencode($value) . "\"";
    	$r .= implode(', ', $values);
    	return $r;
    }
    
    // Set up the oauth Authorization array
    $oauth = array(
    	'oauth_consumer_key' => $config['consumer_key'],
    	'oauth_nonce' => time(),
    	'oauth_signature_method' => 'HMAC-SHA1',
    	'oauth_token' => $config['oauth_access_token'],
    	'oauth_timestamp' => time(),
    	'oauth_version' => '1.0'
    );
    	
    $base_info = buildBaseString($base_url, 'GET', array_merge($oauth, $url_arguments));
    $composite_key = rawurlencode($config['consumer_secret']) . '&' . rawurlencode($config['oauth_access_token_secret']);
    $oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
    $oauth['oauth_signature'] = $oauth_signature;
    
    // Make Requests
    $header = array(
    	buildAuthorizationHeader($oauth), 
    	'Expect:'
    );
    $options = array(
    	CURLOPT_HTTPHEADER => $header,
    	//CURLOPT_POSTFIELDS => $postfields,
    	CURLOPT_HEADER => false,
    	CURLOPT_URL => $full_url,
    	CURLOPT_RETURNTRANSFER => true,
    	CURLOPT_SSL_VERIFYPEER => false
    );
    
    $feed = curl_init();
    curl_setopt_array($feed, $options);
    $result = curl_exec($feed);
    $info = curl_getinfo($feed);
    curl_close($feed);
    
    // Send suitable headers to the end user.
    if(isset($info['content_type']) && isset($info['size_download'])){
    	header('Content-Type: '.$info['content_type']);
    	header('Content-Length: '.$info['size_download']);
    
    }
    
    echo($result);
    ?>

  8. #8
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,407
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    First things first, you should edit your last post right away if you still can and remove your twitter oauth and consumer keys and secrets - other people can abuse your twitter account with those. In fact, you should probably log into the twitter dev site and see if you can renew your access tokens.

    The server is now returning the response: ({"errors":[{"message":"Could not authenticate you","code":32}]});
    (You can check on what the server is returning by visiting: http://www.maxfewtrell.com/assets/sc...callback%3D%3F)

  9. #9
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks, and sorry - I've edited the post and changed my access codes.

    I see the error you're pointing out. Does that mean anything to you?

    Thank you!

  10. #10
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,407
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    The error could mean something as simple as a typo in one of your API keys/tokens.

    Edit: I've seen several conversations over at the twitter dev site that indicate it could be a variety of issues that cause that particular error, so if double-checking the keys/tokens doesn't do it, I know another PHP library you could use which is simpler to get up and running (and which I know works, as I've been using it myself).

  11. #11
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hey!
    Thanks for yet another informative and helpful reply!
    I thought it could be the same thing so I re-checked and re-entered the API keys but to no avail.
    Could we try your PHP library?
    Thank you again!

  12. #12
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,407
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    So, first off you'll need to download the TwitterOAuth library.

    Then, replace the contents of your twitter-proxy.php with this:
    PHP Code:
    <?php
    require_once('twitteroauth/twitteroauth.php');

    // Your API credentials here:
    $consumer_key '';
    $consumer_secret '';
    $access_token '';
    $access_token_secret '';

    $connection = new TwitterOAuth($consumer_key$consumer_secret$access_token$access_token_secret);
    $connection->decode_json FALSE;

    $tweets $connection->get('statuses/user_timeline.json?screen_name=Max_Fewtrell&count=5&include_rts=1&callback=?');

    header('Content-type: application/json');
    echo 
    $tweets;
    I'm assuming all you want to do is pull down a list of your latest tweets, so I've hardcoded the string with the API options here. This means that if you want to change any of the options (e.g number of tweets returned) you'll have to do it here rather than in your JS code, but it leaves the script less open to abuse by malicious users.

  13. #13
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    8Mega, thank you very much for that!

    twitter-proxy.php seems to be outputting something sensible now! However the tweets still aren't coming out on the Twitter feed; I'm still getting 'Loading tweets...'.

    Is it anything to do with this bit of code in the header do you think?

    Code:
    <script>
    jQuery.noConflict();
      function randomString(length) {
        var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split('');
        var str = '';
        for (var i = 0; i < length; i++) {
          str += chars[Math.floor(Math.random() * chars.length)];
        }
        return str;
      }
      var rnd = randomString(8);
    
      jQuery(document).ready(function($) {
        $(".tweet").tweet({
          loading_text: "Loading tweets..."
        });
      })
    </script>

  14. #14
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,407
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    I guess the problem is in /assets/scripts/tweets/jquery.tweet.js
    You need to update the path to the php script, from:
    Code JavaScript:
    twitter_api_url: "twitter-proxy.php?url=",
    to:
    Code JavaScript:
    twitter_api_url: "/assets/scripts/tweets/twitter-proxy.php?url=",

  15. #15
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I updated the line as suggested but it didn't work
    Any other ideas by any chance?
    Thank you!

  16. #16
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,407
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    Hmm, OK well the request is being returned from the server, but the success callback in your JS isn't being fired. Can you try editing this line in your twitter-proxy.php file please, from:
    PHP Code:
    $tweets $connection->get('statuses/user_timeline.json?screen_name=Max_Fewtrell&count=5&include_rts=1&callback=?'); 
    to:
    PHP Code:
    $tweets $connection->get('statuses/user_timeline.json?screen_name=Max_Fewtrell&count=5&include_rts=1'); 

  17. #17
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    YES! Mega, thank you!

    The only thing now is that the API only seems to be calling the latest 2 statuses - from what I can see from the code, it should be calling the latest 5. Do you have any ideas on that?

    Almost there!

    Thank you!

  18. #18
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,407
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    I think we need to make one last tweak to that line of PHP code. Try:
    PHP Code:
    $tweets $connection->get('statuses/user_timeline.json?screen_name=Max_Fewtrell&count=5&include_rts=true'); 
    I think that version 1.1 of the API might need include_rts explicitly set to true, rather than 1.

  19. #19
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It still seems to be just getting the latest two tweets. I can't find 'include_rts' in any of the files...

    Sorry for being an idiot and thank you for being patient with me!

  20. #20
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,407
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    Back in the twitter-proxy.php file, change this line:
    PHP Code:
    $tweets $connection->get('statuses/user_timeline.json?screen_name=Max_Fewtrell&count=5&include_rts=1'); 
    to this:
    PHP Code:
    $tweets $connection->get('statuses/user_timeline.json?screen_name=Max_Fewtrell&count=5&include_rts=true'); 

  21. #21
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Still the same result I'm afraid, sorry!

  22. #22
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,407
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    OK, how about if we remove the include_rts bit altogether, so the code reads:
    PHP Code:
    $tweets $connection->get('statuses/user_timeline.json?screen_name=Max_Fewtrell&count=5'); 
    Does that make a difference?

  23. #23
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    AMAZING!!! Thank you so much so much for all your help and for being patient with me - you've cracked it!
    Really appreciate that - you are a genius!
    Thank you again


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •