<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Joey Rivera &#187; twitter</title>
	<atom:link href="http://www.joeyrivera.com/tag/twitter/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.joeyrivera.com</link>
	<description>Blogging about PHP, Actionscript, MySQL, and other interests.</description>
	<lastBuildDate>Fri, 02 Dec 2011 03:55:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Twitter API, OAuth Authentication, and Zend_Oauth Tutorial</title>
		<link>http://www.joeyrivera.com/2010/twitter-api-oauth-authentication-and-zend_oauth-tutorial/</link>
		<comments>http://www.joeyrivera.com/2010/twitter-api-oauth-authentication-and-zend_oauth-tutorial/#comments</comments>
		<pubDate>Mon, 25 Oct 2010 20:52:03 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[zend_oauth]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=617</guid>
		<description><![CDATA[I recently had to work on a project that required me to interact with the Twitter API. I had done this before so I wasn&#8217;t expecting anything different until I remembered that Twitter had changed their API to start using OAuth for authentication. If you are not familiar with OAuth, it&#8217;s a secure way of [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to work on a project that required me to interact with the Twitter API. I had done this before so I wasn&#8217;t expecting anything different until I remembered that Twitter had changed their API to start using OAuth for authentication. If you are not familiar with OAuth, it&#8217;s a secure way of authenticating without requiring a user to submit their username and password to third-parties &#8211; you can read more about it at <a title="OAuth Website" href="http://oauth.net/">OAuth</a>. There are lots of resources online that talk about this in detail but I wasn&#8217;t able to find one that explained the entire process in a way that made sense. Hopefully this post will give you everything you need to get started with the Twitter API. I&#8217;m going to go through the steps required to make this work without using the entire zend framework.</p>
<h2>Objective</h2>
<p>This tutorial will go step-by-step in explaining how to create a small PHP application that can interact with the Twitter API. Our goal is to:</p>
<ul>
<li>Authenticate</li>
<li>Display our latest tweets</li>
<li>Post new tweets from PHP</li>
<li>Display the last few times our account was mentioned</li>
</ul>
<p>The only assumptions at this point (other than knowing PHP) is that you have a twitter account and the zend framework library <a title="Get the Zend Framework" href="http://framework.zend.com/download/latest">downloaded</a>. We won&#8217;t be using the entire framework, just some of the files as standalone modules.</p>
<h2>Registering An App</h2>
<p>The first step in being able to communicate with the Twitter API is to register an app in their system so you can receive all the necessary keys to authenticate with OAuth. Go to <a title="Twitter Developer" href="http://dev.twitter.com/">dev.twitter.com</a> and log in with your Twitter account. Now click on &#8216;register an app&#8217; (if that link is not visible then click on &#8216;your apps&#8217; on the top right and then click on &#8216;register an app&#8217; in the next page). These are the values I put in the form on the next page for my app. Feel free to follow along. I&#8217;ll explain the important inputs.</p>
<p><strong>Application:</strong> Joey&#8217;s Blog Example<br />
<strong>Description:</strong> Twitter PHP App<br />
<strong>Application Website:</strong> http://www.joeyrivera.com<br />
<strong>Organization:</strong> None<br />
<strong>Application Type:</strong> Browser<br />
<strong>Callback URL:</strong> http://www.joeyrivera.com/twitter/callback.php<br />
<strong>Default Access Type:</strong> Read &amp; Write<span id="more-617"></span></p>
<p>Most of the above are self-explanatory but let me explain callback since it&#8217;s an important one. Before we can talk to Twitter, we need to authenticate to get a token from Twitter. Once we have our token, we can start calling the API. During authentication, we are actually going to leave our application and go to Twitters website where the user will have to enter their twitter credentials. After the user allows our application and is done authenticating, Twitter will redirect the user back to our applications callback url. We haven&#8217;t created the file yet, but point back to a file called &#8216;callback.php&#8217; where you plan on putting this file. We will create this file later. (I mentioned users don&#8217;t have to give third-parties their user/pass but they still have to let Twitter know it&#8217;s ok for this app to access their account.)</p>
<p>Enter the captcha and register. At this point we have successfully registered our app that can now start communicating with the Twitter API.</p>
<h2>Authenticating</h2>
<p>To authenticate using Zend_Oauth we need to create a consumer object. The consumer needs an array with the following parameters:</p>
<ul>
<li>callbackUrl: Same as the one used during &#8216;registering an app&#8217;.</li>
<li>siteUrl: The url where the token request will take place. In this case: &#8216;http://twitter.com/oauth&#8217;.</li>
<li>consumerKey: This value is assigned to you after registering your app. To get this value, log into dev.twitter.com, go to your apps, and select the app you just created during &#8216;registering an app&#8217; above. All your keys/secret and info will be listed on that page.</li>
<li>consumerSecret: same steps as consumerKey.</li>
</ul>
<p>We are going to be using the code from <a href="http://framework.zend.com/manual/en/zend.oauth.introduction.html">zend docs</a> with a couple minor tweaks or additions. The code is below:</p>
<h4>authenticate.php</h4>
<div class="dean_ch" style="white-space: wrap;"><a href="http://www.php.net/session_start"><span class="kw3">session_start</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><a href="http://www.php.net/set_include_path"><span class="kw3">set_include_path</span></a><span class="br0">&#40;</span><span class="st0">&#8216;/path/to/zend/library/1.10.8&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">require</span> <span class="st0">&#8216;Zend/Oauth/Consumer.php&#8217;</span>;</p>
<p><span class="re0">$config</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">&#8216;callbackUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://www.joeyrivera.com/twitter/callback.php&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;siteUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://twitter.com/oauth&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerKey&#8217;</span> =&gt; <span class="st0">&#8216;ASD234ADF34ADSF&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerSecret&#8217;</span> =&gt; <span class="st0">&#8217;24GH789JSDFGDFG345098DF09873SDFSD&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$consumer</span> = <span class="kw2">new</span> Zend_Oauth_Consumer<span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span>;</p>
<p><span class="co1">// fetch a request token</span><br />
<span class="re0">$token</span> = <span class="re0">$consumer</span>-&gt;<span class="me1">getRequestToken</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="co1">// persist the token to storage</span><br />
<span class="re0">$_SESSION</span><span class="br0">&#91;</span><span class="st0">&#8216;TWITTER_REQUEST_TOKEN&#8217;</span><span class="br0">&#93;</span> = <a href="http://www.php.net/serialize"><span class="kw3">serialize</span></a><span class="br0">&#40;</span><span class="re0">$token</span><span class="br0">&#41;</span>;</p>
<p><span class="co1">// redirect the user</span><br />
<span class="re0">$consumer</span>-&gt;<span class="me1">redirect</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
<p>Create a file and paste the above code in there and save your file as authenticate.php. Go back and modify the values of the $config array to use your callbackUrl, siteUrl, consumerKey, and consumerSecret. Also make sure to modify the include path to include your library folder where the zend framework resides (I&#8217;m using the framework version 1.10.8 for these examples).</p>
<p>Quick explanation of the code. First we start our session since we&#8217;ll be using a session variable to track the request token needed to create the access token later. Then we create a consumer and create the request token. Finally we call redirect on the consumer which sends us to twitter feeding it all the necessary information in the proper format for us to then authenticate. There is lots of magic going on behind the scene and for a better understanding on how the token and signature works read the OAuth docs. I personally find it much easier to use Zend_Oauth instead.</p>
<p>Now lets create the callback file, code is below:</p>
<h4>callback.php</h4>
<div class="dean_ch" style="white-space: wrap;"><a href="http://www.php.net/session_start"><span class="kw3">session_start</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><a href="http://www.php.net/set_include_path"><span class="kw3">set_include_path</span></a><span class="br0">&#40;</span><span class="st0">&#8216;/path/to/zend/library/1.10.8&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">require</span> <span class="st0">&#8216;Zend/Oauth/Consumer.php&#8217;</span>;</p>
<p><span class="re0">$config</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">&#8216;callbackUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://www.joeyrivera.com/twitter/callback.php&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;siteUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://twitter.com/oauth&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerKey&#8217;</span> =&gt; <span class="st0">&#8216;ASD234ADF34ADSF&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerSecret&#8217;</span> =&gt; <span class="st0">&#8217;24GH789JSDFGDFG345098DF09873SDFSD&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$consumer</span> = <span class="kw2">new</span> Zend_Oauth_Consumer<span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span>;</p>
<p><span class="kw1">if</span> <span class="br0">&#40;</span>!<a href="http://www.php.net/empty"><span class="kw3">empty</span></a><span class="br0">&#40;</span><span class="re0">$_GET</span><span class="br0">&#41;</span> &amp;amp;&amp;amp; <a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$_SESSION</span><span class="br0">&#91;</span><span class="st0">&#8216;TWITTER_REQUEST_TOKEN&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$token</span> = <span class="re0">$consumer</span>-&gt;<span class="me1">getAccessToken</span><span class="br0">&#40;</span><span class="re0">$_GET</span>, <a href="http://www.php.net/unserialize"><span class="kw3">unserialize</span></a><span class="br0">&#40;</span><span class="re0">$_SESSION</span><span class="br0">&#91;</span><span class="st0">&#8216;TWITTER_REQUEST_TOKEN&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// Now that we have an Access Token, we can discard the Request Token</span><br />
&nbsp; &nbsp; <span class="re0">$_SESSION</span><span class="br0">&#91;</span><span class="st0">&#8216;TWITTER_REQUEST_TOKEN&#8217;</span><span class="br0">&#93;</span> = <span class="kw2">null</span>;<br />
<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co1">// Mistaken request? Some malfeasant trying something?</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="br0">&#40;</span><span class="st0">&#8216;Invalid callback request. Oops. Sorry.&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></p>
<p><span class="co1">// save token to file</span><br />
file_put_contents<span class="br0">&#40;</span><span class="st0">&#8216;token.txt&#8217;</span>, <a href="http://www.php.net/serialize"><span class="kw3">serialize</span></a><span class="br0">&#40;</span><span class="re0">$token</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
<p>Save this file as callback.php after modifying the $config variables and library path just like with authenticate.php. We are once again starting our session to be able to capture the &#8216;TWITTER_REQUEST_TOKEN&#8217; created in the previous step. Then we create the consumer again and check to make sure the session is there and that we received query string parameters from Twitter. If everything is as expected, we feed the consumer all the information and ask it for an access token. This is the token we need to track since it&#8217;s the token we need for any call our application makes to the Twitter API. Since we no longer need the request token, we can remove it from the session.</p>
<p>The last step is to save the token somewhere so we can reuse it and not have to authenticate again. Twitter&#8217;s access token does not expire (at least not now). This means, once we authenticate with Twitter, as long as we have our access token stored and accessible to us, our client will not have to authenticate again (assuming Twitter doesn&#8217;t change their mind later and adds an expiration to their tokens). For the purpose of this example, I&#8217;m storing this token in the file system. Another option is to store this value in the database, it&#8217;s really up to you where you want to put it. If you are saving it to the file system, make sure that file is writable by your application.</p>
<p>Both files are created so lets try it out. Go to your browser and access the authenticate.php file. When the page loads, you should be redirected to Twitter and asked to log in (unless you are already logged into Twitter). Enter your twitter account user/pass that you want to access and continue. Next you&#8217;ll be asked if you want to allow this application to access your account. Go ahead and click allow, then you&#8217;ll be taken to your callback.php url. At this point we have authorized, received our access token, and stored it. Now we are done with our first goal and ready for the good stuff.</p>
<h2>Using our Token</h2>
<p>Our next goal was to display our latest tweets so this will be our first example on how to use our token. Technically, this isn&#8217;t the best example as you don&#8217;t need to authenticate with Twitter to display public user tweets but you&#8217;ll still get to see how to make a call to the Twitter API using our token.</p>
<h4>show_tweets.php</h4>
<div class="dean_ch" style="white-space: wrap;"><a href="http://www.php.net/set_include_path"><span class="kw3">set_include_path</span></a><span class="br0">&#40;</span><span class="st0">&#8216;/path/to/zend/library/1.10.8&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">require</span> <span class="st0">&#8216;Zend/Oauth/Consumer.php&#8217;</span>;</p>
<p><span class="re0">$config</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">&#8216;callbackUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://www.joeyrivera.com/twitter/callback.php&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;siteUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://twitter.com/oauth&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerKey&#8217;</span> =&gt; <span class="st0">&#8216;ASD234ADF34ADSF&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerSecret&#8217;</span> =&gt; <span class="st0">&#8217;24GH789JSDFGDFG345098DF09873SDFSD&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$token</span> = <a href="http://www.php.net/unserialize"><span class="kw3">unserialize</span></a><span class="br0">&#40;</span><a href="http://www.php.net/file_get_contents"><span class="kw3">file_get_contents</span></a><span class="br0">&#40;</span><span class="st0">&#8216;token.txt&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$client</span> = <span class="re0">$token</span>-&gt;<span class="me1">getHttpClient</span><span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setUri</span><span class="br0">&#40;</span><span class="st0">&#8216;http://twitter.com/statuses/user_timeline.json&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setMethod</span><span class="br0">&#40;</span>Zend_Http_Client::<span class="me2">GET</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setParameterGet</span><span class="br0">&#40;</span><span class="st0">&#8216;screen_name&#8217;</span>, <span class="st0">&#8216;joeyrivera&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setParameterGet</span><span class="br0">&#40;</span><span class="st0">&#8216;count&#8217;</span>, <span class="st0">&#8217;10&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$response</span> = <span class="re0">$client</span>-&gt;<span class="me1">request</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$tweets</span> = json_decode<span class="br0">&#40;</span><span class="re0">$response</span>-&gt;<span class="me1">getBody</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$tweets</span> <span class="kw1">as</span> <span class="re0">$tweet</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$tweet</span>-&gt;<span class="me1">text</span>, <span class="st0">&quot;&lt;br&gt;&quot;</span>;<br />
<span class="br0">&#125;</span></div>
<p>Paste the above code into a file called show_tweets.php and edit the configs yet again plus the library. At this point I&#8217;ll stop mentioning to edit the config and library &#8211; just remember to do the same with the next couple examples. First we get our token which we saved to a file during the callback phase. Then we create a client object, tell it what url to call, the method to use and pass two params to let the API know who&#8217;s tweets we want and how many tweets to return. Finally we tell the client to initiate the request and we display it when it comes back.</p>
<p>Where did I get the uri from? from Twitters docs page. Spend some time there learning all the different methods you can call and what the required parameters are. For <a title="User Timeline" href="http://dev.twitter.com/doc/get/statuses/user_timeline">user_timeline</a> (which is what we want to get our latest tweets) we need to call the uri used above. The last part, the .json at the end tells Twitter that we want a JSON encoded response back which is why we need to do a json_decode on the body to view it. You could have used .xml if you wanted an xml back instead. The docs for user_timeline also specify you need to do a get which is why we set it as a method and add the two get parameters. There are more parameters you can set if you like.</p>
<p>This is what I see when I run this page with my screen name:</p>
<pre>Flash, jQuery, and Php - what a pain you have all been to me today but I'm glad all is well again.
Put my car up on autotrader, check it out if you are in the market for a 2005 Subaru WRX STi or know someone who might: http://is.gd/g3tqv
someone owns a image rollover patent? http://arstechnica.com/tech-policy/news/2010/10/patent-troll-takes-over-the-web-can-it-be-stopped.ars
Microsoft has the best commercials! http://holykaw.alltop.com/microsoft-pokes-fun-at-smartphone-users-in-ne
Finally got oAuth working to post to Twitter from PHP.
Accidentally found this very cool video by RefinedData http://refineddata.com/products/refinedtraining/index.php
You guys have recommendations on course authoring tools like articulate/captivate that don't have a player. Just a place to create content?
Cool story on YouTube instant http://www.feross.org/youtube-instant-media-frenzy/ Congrats to Feross on the accomplishment.
After driving a Z06 Corvette, I have become a believer of American muscle. STi was fun but just doesn't compare to a Z06.
Been week since we paid for Adobe developer support license and we are still not closer to solving our problem. Hoping to make progress soon</pre>
<p>Now lets submit a tweet.</p>
<h4>submit_tweet.php</h4>
<div class="dean_ch" style="white-space: wrap;"><a href="http://www.php.net/set_include_path"><span class="kw3">set_include_path</span></a><span class="br0">&#40;</span><span class="st0">&#8216;/path/to/zend/library/1.10.8&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">require</span> <span class="st0">&#8216;Zend/Oauth/Consumer.php&#8217;</span>;</p>
<p><span class="re0">$config</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">&#8216;callbackUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://www.joeyrivera.com/twitter/callback.php&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;siteUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://twitter.com/oauth&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerKey&#8217;</span> =&gt; <span class="st0">&#8216;ASD234ADF34ADSF&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerSecret&#8217;</span> =&gt; <span class="st0">&#8217;24GH789JSDFGDFG345098DF09873SDFSD&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$token</span> = <a href="http://www.php.net/unserialize"><span class="kw3">unserialize</span></a><span class="br0">&#40;</span><a href="http://www.php.net/file_get_contents"><span class="kw3">file_get_contents</span></a><span class="br0">&#40;</span><span class="st0">&#8216;token.txt&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$client</span> = <span class="re0">$token</span>-&gt;<span class="me1">getHttpClient</span><span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setUri</span><span class="br0">&#40;</span><span class="st0">&#8216;http://twitter.com/statuses/update.json&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setMethod</span><span class="br0">&#40;</span>Zend_Http_Client::<span class="me2">POST</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setParameterPost</span><span class="br0">&#40;</span><span class="st0">&#8216;status&#8217;</span>, <span class="st0">&#8216;I hope to get my blog post on Twitter API with Zend_Oauth up in the next day.&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$response</span> = <span class="re0">$client</span>-&gt;<span class="me1">request</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$data</span> = json_decode<span class="br0">&#40;</span><span class="re0">$response</span>-&gt;<span class="me1">getBody</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$data</span>-&gt;<span class="me1">text</span>;</div>
<p>The code is very similar. The resource we want to call this time is <a title="Statuses/Update" href="http://dev.twitter.com/doc/post/statuses/update">statuses/update</a>. It requires a post method so we use POST and setParameterPost instead of GET. The one required param is status &#8211; set that to the string you want to tweet and run this page. Now go check your tweeter account and you should have that status show up. Make sure the string you pass is 140 characters or less. Also, twitter won&#8217;t allow you to submit two identical statuses so if you are testing this code and it&#8217;s not working, make sure you are sending a unique string.</p>
<p>Finally we&#8217;ll create one last example that displays the last 5 mentions of our twitter account.</p>
<h4>mentioned_tweet.php</h4>
<div class="dean_ch" style="white-space: wrap;"><a href="http://www.php.net/set_include_path"><span class="kw3">set_include_path</span></a><span class="br0">&#40;</span><span class="st0">&#8216;/path/to/zend/library/1.10.8&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">require</span> <span class="st0">&#8216;Zend/Oauth/Consumer.php&#8217;</span>;</p>
<p><span class="re0">$config</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">&#8216;callbackUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://www.joeyrivera.com/twitter/callback.php&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;siteUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://twitter.com/oauth&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerKey&#8217;</span> =&gt; <span class="st0">&#8216;ASD234ADF34ADSF&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerSecret&#8217;</span> =&gt; <span class="st0">&#8217;24GH789JSDFGDFG345098DF09873SDFSD&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$token</span> = <a href="http://www.php.net/unserialize"><span class="kw3">unserialize</span></a><span class="br0">&#40;</span><a href="http://www.php.net/file_get_contents"><span class="kw3">file_get_contents</span></a><span class="br0">&#40;</span><span class="st0">&#8216;token.txt&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$client</span> = <span class="re0">$token</span>-&gt;<span class="me1">getHttpClient</span><span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setUri</span><span class="br0">&#40;</span><span class="st0">&#8216;http://twitter.com/statuses/mentions.json&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setMethod</span><span class="br0">&#40;</span>Zend_Http_Client::<span class="me2">GET</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setParameterGet</span><span class="br0">&#40;</span><span class="st0">&#8216;count&#8217;</span>, <span class="st0">&#8217;5&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$response</span> = <span class="re0">$client</span>-&gt;<span class="me1">request</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$tweets</span> = json_decode<span class="br0">&#40;</span><span class="re0">$response</span>-&gt;<span class="me1">getBody</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$tweets</span> <span class="kw1">as</span> <span class="re0">$tweet</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$tweet</span>-&gt;<span class="me1">text</span>, <span class="st0">&quot;&lt;br&gt;&quot;</span>;<br />
<span class="br0">&#125;</span></div>
<p>The <a title="Mentions" href="http://dev.twitter.com/doc/get/statuses/mentions">mentions</a> resource uses GET and doesn&#8217;t require any parameter. I&#8217;m passing a count of 5 so you don&#8217;t get too much back. Here is what I see when I run this page:</p>
<pre>heads up! @mosesngone and @joeyrivera consuming Web Services Nov 4th @atlantaphp #atlantaphp http://meetu.ps/3Rbt</pre>
<h2>Conclusion</h2>
<p>Using Zend_Oauth it&#8217;s really easy to authenticate with OAuth and track your token. At that point calling the Twitter API is very simple. I want to thank the guys at Zend for making our lives so much easier with all these great modules. If you have any question feel free to ask. Hopefully you have all found this post very informative and helpful.</p>
<p>EDIT: Here is a similar post on using <a title="Joey Rivera Facebook Graph API and PHP SDK Post" href="http://www.joeyrivera.com/2010/facebook-graph-api-app-easy-w-php-sdk/">Facebooks Graph API with their PHP SDK</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2010/twitter-api-oauth-authentication-and-zend_oauth-tutorial/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>Using Zend_Paginator with Twitter API and Zend_Cache</title>
		<link>http://www.joeyrivera.com/2010/using-zend_paginator-with-twitter-api-and-zend_cache/</link>
		<comments>http://www.joeyrivera.com/2010/using-zend_paginator-with-twitter-api-and-zend_cache/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 19:15:08 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[twitter api]]></category>
		<category><![CDATA[twitter services]]></category>
		<category><![CDATA[zend_cache]]></category>
		<category><![CDATA[zend_paginator]]></category>
		<category><![CDATA[zend_rest_client]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=545</guid>
		<description><![CDATA[Zend Framework 1.10.0 is out and a comment was posted on my blog that lead me to creating this new post. I&#8217;m going to focus more on Zend_Paginator and Zend_Rest_Client to access Twitters API since I&#8217;ve already created a post on Zend_Cache. Normally, I would use Zend_Service_Twitter to access the twitter service but it still [...]]]></description>
			<content:encoded><![CDATA[<p>Zend Framework 1.10.0 is out and a comment was posted on my blog that lead me to creating this new post. I&#8217;m going to focus more on Zend_Paginator and Zend_Rest_Client to access Twitters API since I&#8217;ve already created a post on <a title="Caching using Zend_Cache" href="http://www.joeyrivera.com/2009/caching-using-phpzend_cache-and-mysql/">Zend_Cache</a>. Normally, I would use <a title="Zend Framework Zend_Service_Twitter" href="http://framework.zend.com/manual/en/zend.service.twitter.html">Zend_Service_Twitter</a> to access the twitter service but it still seems to require authentication to retrieve a users timeline where <a title="Twitter API" href="http://apiwiki.twitter.com/Twitter-REST-API-Method:-statuses-user_timeline?SearchFor=statuses&amp;sp=2">only protected users</a> should require authentication.</p>
<h4>Zend_Paginator</h4>
<p>Zend_Paginator from the Zend Framework site:</p>
<blockquote><p>Zend_Paginator is a flexible component for paginating collections of data and presenting that data to users.</p></blockquote>
<p>Zend_Paginator automatically creates pagination for you by setting up a few parameters and passing it an array of data. What is pagination, if you have ever gone to <a title="Google Search Joey Rivera" href="http://www.google.com/search?rlz=1C1GGLS_enUS291US304&amp;sourceid=chrome&amp;ie=UTF-8&amp;q=joey+rivera">Google</a> and searched for anything, usually you&#8217;ll see something like the following at the bottom of the search results page:</p>
<p style="text-align: center;"><img class="alignnone" title="Google Pagination Example" src="http://farm3.static.flickr.com/2759/4310975845_292c7ffca0_o.gif" alt="" width="267" height="61" /></p>
<p>See the numbers and the text links, this is called pagination. So much data exists for the particular search that it wouldn&#8217;t make sense to display it all in one page. It would cause large amounts of scrolling down to view, the load time of the page would be affected, so we rather show fewer results and give our users the option of viewing more by clicking on the pagination links.</p>
<p>To demonstrate how to use Zend_Paginator I created a sample Zend Framework 1.10.0 application. This application grabs my last 50 tweets using the Twitter API and displays them 10 at a time using Zend_Paginator. I use Zend_Cache to cache my twitter data so I don&#8217;t have to spend time accessing their api every time &#8211; I&#8217;m sure they would appreciate it.</p>
<h4>Bootstrap</h4>
<p>The first step was to create a new zend framework project. I&#8217;m making the assumption that if you are reading this then you already know how to do this. After creating my new project, I added two methods to my bootstrap file to autoload and to init Zend_Cache. My bootstrap looks like the following:<br />
<span id="more-545"></span></p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">class</span> Bootstrap <span class="kw2">extends</span> Zend_Application_Bootstrap_Bootstrap<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; protected <span class="kw2">function</span> _initAutoload<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$autoloader</span> = <span class="kw2">new</span> Zend_Application_Module_Autoloader<span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;namespace&#8217;</span> =&gt; <span class="st0">&#8216;My&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;basePath&#8217;</span> &nbsp;=&gt; APPLICATION_PATH,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; protected <span class="kw2">function</span> _initCache<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$front</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;lifetime&#8217;</span> =&gt; <span class="nu0">10</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;automatic_serialization&#8217;</span> =&gt; <span class="kw2">true</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$back</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;cache_dir&#8217;</span> =&gt; APPLICATION_PATH . <span class="st0">&#8216;/../cache&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cache</span> = Zend_Cache::<span class="me2">factory</span><span class="br0">&#40;</span><span class="st0">&#8216;Core&#8217;</span>, <span class="st0">&#8216;File&#8217;</span>, <span class="re0">$front</span>, <span class="re0">$back</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Zend_Registry::<span class="me2">set</span><span class="br0">&#40;</span><span class="st0">&#8216;cache&#8217;</span>, <span class="re0">$cache</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p>For caching to work correctly, I had to create the &#8216;cache&#8217; folder in my site root. Notice I set a cache lifetime in my bootstrap, I&#8217;ll be overriding it later for my twitter service. I like to set a general lifetime when caching and override the items that I believe need a different lifetime value.</p>
<h4>Twitter Service</h4>
<p>Next was creating my twitter service. I added a folder &#8216;service&#8217; under &#8216;application&#8217; and created a file called &#8216;Twitter.php&#8217;. Here is the content for that file:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">class</span> My_Service_Twitter<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; const CACHELIFETIME = <span class="nu0">3600</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; protected <span class="re0">$_screen_name</span> = <span class="kw2">null</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; protected <span class="re0">$_cache</span> = <span class="kw2">null</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> __construct<span class="br0">&#40;</span><span class="re0">$screen_name</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;_screen_name = <span class="re0">$screen_name</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;_cache = Zend_Registry::<span class="me2">get</span><span class="br0">&#40;</span><span class="st0">&#8216;cache&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> getUserTimeline<span class="br0">&#40;</span><span class="re0">$count</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cache_id</span> = <span class="st0">&#8216;twitter_&#8217;</span> . <span class="re0">$this</span>-&gt;_screen_name . <span class="re0">$count</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>!<span class="br0">&#40;</span><span class="re0">$data</span> = <span class="re0">$this</span>-&gt;_cache-&gt;<span class="me1">load</span><span class="br0">&#40;</span><span class="re0">$cache_id</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$client</span> = <span class="kw2">new</span> Zend_Rest_Client<span class="br0">&#40;</span><span class="st0">&#8216;http://twitter.com/statuses/user_timeline.xml&#8217;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// setup params for service call</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$client</span>-&gt;<span class="me1">screen_name</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;_screen_name<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$client</span>-&gt;<span class="me1">count</span><span class="br0">&#40;</span><span class="re0">$count</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// call service and get all data</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$raw_data</span> = <span class="re0">$client</span>-&gt;<span class="me1">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// create array with the data we want &#8211; text is the actual tweet 140 chars</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>!<a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$raw_data</span>-&gt;<span class="me1">error</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$raw_data</span>-&gt;<span class="me1">status</span> <span class="kw1">as</span> <span class="re0">$tweet</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span><span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;text&#8217;</span><span class="br0">&#93;</span> = <span class="br0">&#40;</span>string<span class="br0">&#41;</span><span class="re0">$tweet</span>-&gt;<span class="me1">text</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// save array to cache &#8211; override cache lifetime</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;_cache-&gt;<span class="me1">save</span><span class="br0">&#40;</span><span class="re0">$data</span>, <span class="re0">$cache_id</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;twitter&#8217;</span><span class="br0">&#41;</span>, self::<span class="me2">CACHELIFETIME</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$data</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p>Let me explain what I&#8217;m doing here. First I setup some variables. I setup the cache lifetime var to an hour since I don&#8217;t want to be hitting twitter to often and I don&#8217;t tweet more than a couple times a day anyways. In the construct, I simply set my class properties. Twitter API has various service calls you can make. For the purpose of this app, I simply want to return the last 50 tweets posted by a public user &#8211; me. If you look at the twitter docs, you&#8217;ll see <a title="Twitter Statuses User Timeline Method" href="http://apiwiki.twitter.com/Twitter-REST-API-Method:-statuses-user_timeline?SearchFor=statuses&amp;sp=2">statuses user_timeline</a> will give us just that. The call to the service is very simple. We create a Zend_Rest_Client instance to the service url: http://twitter.com/statuses/user_timeline.xml. Then we setup both parameters (check the link to the twitter api to see the rest of the available params) screen name (the twitter account you are looking for) and count (how many tweets to get back) and call $client-&gt;get(). When I get the raw data from twitter, I create an array storing only the data I need which is text (the actual content of your tweets 140 characters).</p>
<p>Easy enough? I thought so. You&#8217;ll also notice that this functionality is wrapped with caching code. Before calling the service, I check to see if this information is already cached and valid. If so, I just return the cached array else I call the service and store the array in cache. More info my <a title="Caching using PHP/Zend_Cache and MySQL" href="http://www.joeyrivera.com/2009/caching-using-phpzend_cache-and-mysql/">Zend_Cache</a> post on how Zend_Cache works.</p>
<h4>IndexController</h4>
<p>Next I added the following call to my IndexController:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">public</span> <span class="kw2">function</span> indexAction<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co1">// needed vars</span><br />
&nbsp; &nbsp; <span class="re0">$screen_name</span> = <span class="st0">&#8216;joeyrivera&#8217;</span>;<br />
&nbsp; &nbsp; <span class="re0">$total_tweets</span> = <span class="nu0">50</span>;<br />
&nbsp; &nbsp; <span class="re0">$tweets_per_page</span> = &nbsp;<span class="nu0">10</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// get tweets</span><br />
&nbsp; &nbsp; <span class="re0">$service</span> = <span class="kw2">new</span> My_Service_Twitter<span class="br0">&#40;</span><span class="re0">$screen_name</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="re0">$data</span> = <span class="re0">$service</span>-&gt;<span class="me1">getUserTimeline</span><span class="br0">&#40;</span><span class="re0">$total_tweets</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// init paginator</span><br />
&nbsp; &nbsp; <span class="re0">$paginator</span> = Zend_Paginator::<span class="me2">factory</span><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="re0">$paginator</span>-&gt;<span class="me1">setItemCountPerPage</span><span class="br0">&#40;</span><span class="re0">$tweets_per_page</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;<span class="me1">setCurrentPageNumber</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;_getParam<span class="br0">&#40;</span><span class="st0">&#8216;page&#8217;</span>, <span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// send paginator to view</span><br />
&nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">view</span>-&gt;<span class="me1">paginator</span> = <span class="re0">$paginator</span>;<br />
<span class="br0">&#125;</span></div>
<p>I started by setting up required params. Then initializing My_Service_Twitter and calling the getUserTimeline method.$data gets all 50 tweets from Twitter through Zend_Rest_Client or loaded straight from the cache. Last few steps are calling Zend_Paginator::factory and passing in the $data array of tweets. The next line sets the number of items we want displayed per page and sets the current page number &#8211; the page querystring variable (<a title="Zend_Paginator Config" href="http://framework.zend.com/manual/en/zend.paginator.configuration.html">more options here</a>). This last part will make sense soon when I show you the pagination.phtml (the actual pagination controls) file that renders the page numbers and previous/next links in the view. Since we are done with our paginator var, we pass it to our view to display.</p>
<h4>Index View</h4>
<p>The view is pretty simple, all it does is display the list of tweets, 10 tweets per page. It also needs to display the pagination controls which is the file I mentioned earlier. Here is the index.phtml file:</p>
<div class="dean_ch" style="white-space: wrap;">&lt; ?php <span class="kw1">if</span> <span class="br0">&#40;</span><a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">paginator</span><span class="br0">&#41;</span><span class="br0">&#41;</span>: <span class="kw2">?&gt;</span><br />
&lt;ul&gt;<br />
&lt; ?php <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">paginator</span> <span class="kw1">as</span> <span class="re0">$item</span><span class="br0">&#41;</span>: <span class="kw2">?&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;li&gt;&lt; ?php <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$item</span><span class="br0">&#91;</span><span class="st0">&#8216;text&#8217;</span><span class="br0">&#93;</span>; ?&gt;&lt;/li&gt;<br />
&lt; ?php <span class="kw1">endforeach</span>; ?&gt;&lt;/ul&gt;<br />
&lt; ?php <span class="kw1">endif</span>; <span class="kw2">?&gt;</span></p>
<p>&lt; ?php <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$this</span>-&gt;<span class="me1">paginationControl</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">paginator</span>, <span class="st0">&#8216;Sliding&#8217;</span>, <span class="st0">&#8216;pagination.phtml&#8217;</span><span class="br0">&#41;</span>; <span class="kw2">?&gt;</span></div>
<p>If any items are found, the loop takes place and the items are displayed in the list. Zend_Paginator takes care of handling how many items to show and for what page using that parameters we setup earlier. The last line is important. There are different styles you can use when displaying your pagination such as &#8216;sliding&#8217;, &#8216;jumping&#8217;, &#8216;elastic&#8217; and more. You can read about them all in the <a href="http://framework.zend.com/manual/en/zend.paginator.usage.html">zend docs</a>. &#8216;pagination.phtml&#8217; is the file used to display the page numbers and next/previous links. This file can be made so it&#8217;s reusable across your application and you can customize it anyway you like.</p>
<h4>Pagination.phtml</h4>
<p>Here is my file which is located in my views/scripts/ folder:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">pageCount</span> == <span class="nu0">1</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span>;<br />
<span class="br0">&#125;</span></p>
<p><span class="co1">// previous</span><br />
<span class="kw1">if</span><span class="br0">&#40;</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">previous</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216;&lt;a href=&quot;&#8217;</span>.<span class="re0">$this</span>-&gt;<span class="me1">url</span><span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;page&#8217;</span> =&gt; <span class="re0">$this</span>-&gt;<span class="me1">previous</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="st0">&#8216;&quot;&gt;&lt; Previous&lt;/a&gt; &#8216;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw1">else</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216;&lt; Previous &#8216;</span>; <span class="br0">&#125;</span> <span class="co1">// pages foreach($this-&gt;pagesInRange as $page)</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$page</span> != <span class="re0">$this</span>-&gt;<span class="me1">current</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216; &lt;a href=&quot;&#8217;</span>.<span class="re0">$this</span>-&gt;<span class="me1">url</span><span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;page&#8217;</span> =&gt; <span class="re0">$page</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="st0">&#8216;&quot;&gt;&#8217;</span>.<span class="re0">$page</span>.<span class="st0">&#8216;&lt;/a&gt; &#8216;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216; &#8216;</span>, <span class="re0">$page</span>, <span class="st0">&#8216; &#8216;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="co1">// next</span><br />
<span class="kw1">if</span><span class="br0">&#40;</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">next</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216; &lt;a href=&quot;&#8217;</span>.<span class="re0">$this</span>-&gt;<span class="me1">url</span><span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;page&#8217;</span> =&gt; <span class="re0">$this</span>-&gt;<span class="me1">next</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="st0">&#8216;&quot;&gt;Next &gt;&lt;/a&gt;&#8217;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw1">else</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216; Next &gt;&#8217;</span>;<br />
<span class="br0">&#125;</span></div>
<p>If there is only 1 page, do nothing else display the page numbers and if there is a previous or next page, display those links as well. Notice I&#8217;m setting a page variable to add to my querystring. This is so Zend_Paginator knows what page I&#8217;m currently at and can display the correct items. For example: &#8216;www.myapp.com/index/index/&#8217; would default to page one. &#8216;www.myapp.com/index/index/page/3&#8242; would let paginator know we want to display the items that belong to page 3. It also lets the pagination.phtml file know if there is a page 2 and/or 4 to display a back and previous link.</p>
<p style="text-align: left;">Here is a image of the end result:<br />
<img class="aligncenter" src="http://farm5.static.flickr.com/4051/4311491187_79fd88ec56_o.gif" alt="" width="549" height="168" /></p>
<h4>Final Thoughts</h4>
<p>That&#8217;s pretty much it. Hopefully I&#8217;m not forgetting anything. Notice I don&#8217;t have any filtering/validating anywhere. I just wrote this quickly to give a basic understanding on how to use these modules together. I think I&#8217;m going to update my &#8216;Interesting Images&#8217; and &#8216;Interesting Links&#8217; widgets on my sidebar to use pagination and allow users to view older entries.</p>
<p>Something to keep in mind for optimization purposes. Depending on where you are getting your data and how much data you want, it makes more sense to get a total number of items to get an idea of how many pages you need (not get all the data at once!). Then for each page you can get the data that needs to be displayed. For example, I would never call twitter and say: bring back my last one thousand tweets just so I can display 10 on a page and one hundred page numbers. That would be an extreme waste of resources. Instead, I could ask Twitter: how many tweets do I have in total which is all I need to draw my pagination. Then for each page, I can download the data I need and display.</p>
<p>Feel free to leave any questions or comments!</p>
<p>EDIT: Created new post on <a title="Twitter API and OAuth" href="http://www.joeyrivera.com/2010/twitter-api-oauth-authentication-and-zend_oauth-tutorial/" target="_self">using Twitter API and OAuth</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2010/using-zend_paginator-with-twitter-api-and-zend_cache/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>

