Difference between #6 and #5 of How To Connect With Twitter From Yii

unchanged
Title
How To Connect With Twitter From Yii
unchanged
Category
Tutorials
changed
Tags
twitter
changed
Content
Here is a quick tutorial for connecting Yii with Twitter using the [Pogostick
Yii Extensions
Library](http://www.yiiframework.com/extension/ps-yii-extensions/).

First off, you must have the psYiiExtensions installed on your web server and
Yii has to know about it. Please see the installation instructions for more
information.

Secondly, you must have the PHP oauth extension loaded. Details for installing
this are on the [psYiiExtensions
wiki](http://code.google.com/p/ps-yii-extensions/wiki/PHPOAuthSupport).

OAuth
=====-----
The Twitter API uses OAuth as a method of remote authentication. I do not claim
to be an OAuth expert, I just coded a wrapper for the excellent PHP oauth
extension. However, in doing so I did learn a little which I will impart upon
you now.

OAuth is a token based system. That is to say, once a user has been
authenticated by the Twitter server, you are issued a token. This token is used
to communicate with Twitter on the users' behalf until the user deletes the
permissions for your application ON Twitter. For you Facebook app folks, it's
like the old infinite keys.

The process is simple:

1. You obtain a <b>request</b> token from Twitter.
2. Redirect or allow user to click a link to the <b>authorize</b>
URL provided by Twitter.
3. User enters his/her Twitter login information and presses the
"Allow" or "Deny" button (to allow your application access
that is)
4. Twitter redirects the user back to your site's <b>callback
URL</b> (discussed below) with a new token.
5. Your application makes a final call to Twitter to retrieve an
<b>access</b> token using the URL just received during
authentication.

I know, I know, it sounds like a huge mess. And it is. But I've simplified it
consirably as you'll see below.

So follow these steps and you'll be tweeting from your website in no time at
all.

Step 1: Create your Twitter application
=================================---------------------------------------
Before integrating with Twitter, you'll need to create an application on the
Twitter web site. 
This is done by [going here](http://twitter.com/oauth_clients/new)
(http://twitter.com/oauth_clients/new) and filling out the information.
Most of the information asked of you is rudimentary. However, one item deserves
attention. This is the <b>Callback URL</b>.

Callback### Callback URL
------------
The Callback URL is the URL on <b>YOUR</b> web site to which Twitter
will redirect <b>after</b> a user has authenticated against the
Twitter system. 
In my implementation I used a callback url of
http://www.mysite.com/site/twitter.

Save### Save and Create
---------------
Now, press the 'Save' button to create your application.

Consumer### Consumer Key & Secret
---------------------
The top two, the Consumer Key and Consumer Secret are the important ones here. 
These are your API keys. They allow your application to "talk" to
Twitter's API. Copy these down for now, we'll need them in the next step. 
You can always revisit the link above to see them again, so no worries if you've
already clicked-through.

Step 2: Configure Yii
=====================---------------------
Now that you've told Twitter about your application, we need to tell Yii to
create the Twitter component. This is done in the main.php configuration file.
If you have not yet configured your main.php for the psYiiExtension library, do
so now by following the installation instructions.
Add the following code to your 'components' array:

~~~
[php]

		//	Twitter//	Twitter API
		'twitter'
'twitter' => array(
			'class'
    'class' => 'pogostick.components.twitter.CPSTwitterApi',
			'apiKey'
    'apiKey' => 'your_consumer_key',
			'apiSecretKey'
    'apiSecretKey' => 'your_consumer_secret',
			'apiBaseUrl'
    'apiBaseUrl' => 'http://twitter.com',
			'callbackUrl'
    'callbackUrl' => 'your_callback_url',
			'format'
    'format' => 'array',
		),
),  
~~~

Be sure to replace the bold text items with the information you entered and
obtained when you created your Twitter application in step #1.

Step 3: Integration
===================-------------------
There are basically two methods of integrating with Twitter:

* Your site is tweeting updates for itself (or you)

or

* Your site is tweeting on behalf of a user

In either case, you'll need to obtain an access token from the Twitter OAuth
server. This is done by calling the <b>authorize</b> URL. 
In the code sample below is ALL the code from my views/site/twitter.php (also my
callback URL):

~~~
[php]
<?php 
$this->pageTitle=Yii::app()->name . ' - Attach to Twitter';
?>

	<?php 
	$this->pageTitle=Yii::app()->name . ' - Attach to Twitter';
	?>
	
	<?<? if ( ! Yii::app()->twitter->isAuthorized ) {
?>
	<h1>Link
<h1>Link your Twitter Account!</h1>
	
	<div

<div class="yiiForm">
		<?php
    <?php echo CHtml::form(); ?>
			<div
        <div class="simple">
				Click
            Click the button below to be taken to <a
href="http://www.twitter.com/" target=_blank>Twitter</a> to
link your account.
				<br
            <br />
				<br
            <br />
				<br
            <br />
				<a
            <a
href="<?=Yii::app()->twitter->getAuthorizeUrl()?>"><img
src="/images/twitter_sign.png" border="0" alt="Sign in
with Twitter" /></a>
			</div>
		</form>
	</div><!--
        </div>
    </form>
</div><!-- yiiForm -->
	<?
<? } else { ?>
	<h1>Linked
<h1>Linked with Twitter!</h1>
	
	<div

<div class="yiiForm">
		<?php
    <?php echo CHtml::form(); ?>
			<div
        <div class="simple">
				Your
            Your account is currently linked to your Twitter account
<b><?= Yii::app()->twitter->screenName ?>.
				<br
            <br />
				<br
            <br />
				<br
            <br />
			</div>
		</form>
	</div><!--
        </div>
    </form>
</div><!-- yiiForm -->
	<?
<? } ?>
~~~

Capturing the Access Token
--------------------------
After the user has authenticated with Twitter, your callback is called and the
psYiiExtension library will pull out the new token and retrieve the permanent
access token. 
It is up to you to store this someplace. The library places the token in a user
session state. You can retrieve the token via:

~~~
[php]

	ifif ( Yii::app()->twitter->isAuthorized )
		$_arToken
    $_arToken = Yii::app()->twitter->getToken();
	else
		echo
else
    echo 'User is not authorized';
~~~

The token is actually an array with two (or more once authenticated) elements.
After authorization, the array contains the following elements:

<table cellpadding=2 cellspacing=0>
<tr><td>oauth_token</td><td>The access
token</td></tr>
<tr><td>oauth_token_secret</td><td>The access token
secret</td></tr>
<tr><td>user_id</td><td>The user's Twitter numeric user
ID</td></tr>
<tr><td>screen_name</td><td>The user's Twitter screen
name</td></tr>
</table>

Save these off for later use. You can use a session variable or store them in
your database.

### AuthorizationAuthorization Event ###
----------------------
An alternate to this method is to use the <b>onUserAuthorized</b>
event. This event is generated by the CPSOAuthComponent when authorization is
complete. You must subclass CPSTwitterApi to capture this event and do with it
what you please. Not a big deal, and kinda cool, no?

##### Return trips to the site and reloading the
token ##

After the session ends, the tokens are lost and you will need to load up your
stored access tokens for the current user (or your site). This is done via the
<b>CPSTwitterApi::loadData()</b> method.
It is up to you where you do this. Preferably, find a place where you actually
need to use the Twitter API and load it there. Otherwise you'll end up loading
it every time a page is loaded from your site and that's not very fast or
Yii-like.

I ended up creating a subclass of CWebUser called CPSWebUser. Feel free to use
some or all of it. Some incarnation of this will be in the next release of my
library (hence the since 1.0.4).

Here's the code:

~~~
[php]
<?php
/**
 * CPSWebUser class file.
 *
 * @author Jerry Ablan <jablan@pogostick.com>
 * @link http://ps-yii-extensions.googlecode.com
 * @copyright Copyright &copy; 2009 Pogostick, LLC
 * @license http://www.pogostick.com/license/
 */

/**
 * CPS provides
 *
 * @author Jerry Ablan <jablan@pogostick.com>
 * @version SVN: $Id$
 * @package psYiiExtensions
 * @subpackage components
 * @since 1.0.4
 */
class CPSWebUser extends CWebUser
{
	//********************************************************************************	//**************************************************************
	//* Member variables
	//********************************************************************************	//**************************************************************
	
	/**
	* An array of currently authorized platform applications
	* 	
	* @var array
	*/
	protected $m_arAuth = array();
	/**
	* Indicates if platform identities have been loaded...
	* 
	* @var boolean
	*/
	protected $m_bLoaded = false;
	
	//********************************************************************************	//**************************************************************
	//* Private methods
	//********************************************************************************	//**************************************************************
	
	/**
	* Retrieves the user's attached platform accounts
	*/
	public function loadPlatformIdentities( $oPForm = null )
	{
		$_oUser = Yii::app()->user;
		
		if ( ! $_oUser->isGuest )
		{
			//	Load defaults from DB...
			if ( null == $oPForm )
				$oPForm = UserPlatform::model()->findAll( 'user_uid = :user_uid', array(
':user_uid' => $_oUser->id ) );
			
			if ( $oPForm )
			{
				foreach ( $oPForm as $_arRow )
				{
					if ( ! empty( $_arRow->pform_token_text ) )
					{
						$this->m_arAuth[ $_arRow->pform_type_code ] = true;
						
						switch ( $_arRow->pform_type_code )
						{
							case UserPlatform::PTC_TWITTER:
								Yii::app()->twitter->loadData( $_arRow->pform_user_id_text,
$_arRow->pform_user_name_text, true, array( 'oauth_token' =>
$_arRow->pform_token_text, 'oauth_token_secret' =>
$_arRow->pform_token_secret_text ) );
								break;
						}
					}
				}
				
				//	Ok, we've loaded them
				$this->m_bLoaded = true;
			}
		}
	}
	
	//********************************************************************************	//**************************************************************
	//* Yii Overrides
	//********************************************************************************	//**************************************************************
	
	/**
	* Loads identity states from an array and saves them to persistent storage.
	* 
	* @param array $arStates the identity states
	*/
	protected function loadIdentityStates( $arStates )
	{
		//	Call home...
		parent::loadIdentityStates( $arStates );
		
		//	Load our platform identities
		$this->loadPlatformIdentities();
	}
	
	/**
	* Checks if user is authorized with an external application
	* 
	* @param integer $iPTC The platform type code
	* @return boolean
	*/
	public function isAppAuthorized( $iPTC )
	{
		if ( ! $this->m_bLoaded ) $this->loadPlatformIdentities();
		return isset( $this->m_arAuth[ $iPTC ] ) && $this->m_arAuth[
$iPTC ];
	}
	
	/**
	* Handle an application authorization...
	* 
	* @param integer $iPTC The platform type code
	* @param array $arToken The token
	*/
	public function authorizeApp( $iPTC, $arToken = array() )
	{
		$_oUser = User::model()->findByPk( Yii::app()->user->id );
		if ( $_oUser )
		{
			//	Add or update platform 
			if ( ! ( $_oPForm = $_oPForm = UserPlatform::model()->findByPk( array(
'user_uid' => $_oUser->user_uid, 'pform_type_code' => $iPTC ) ) ) )
			{
				$_oPForm = new UserPlatform();
				$_oPForm->user_uid = $_oUser->user_uid;
				$_oPForm->pform_type_code = $iPTC;
			}
			
			if ( isset( $arToken[ 'user_id' ] ) )
			{
				$_oPForm->pform_token_text = $arToken[ 'oauth_token' ];
				$_oPForm->pform_token_secret_text = $arToken[ 'oauth_token_secret' ];
				$_oPForm->pform_user_id_text = $arToken[ 'user_id' ];
				$_oPForm->pform_user_name_text = $arToken[ 'screen_name' ];
				$this->m_arAuth[ $iPTC ] = true;
			}
			else
			{
				$_oPForm->pform_token_text = null;
				$_oPForm->pform_token_secret_text = null;
				$_oPForm->pform_user_id_text = null;
				$_oPForm->pform_user_name_text = null;
			}
			
			//	Save it...
			$_oPForm->save();
			
			//	Initialize the Twitter object
			$this->loadPlatformIdentities( array( $_oPForm ) );
		}
	}
}
~~~

Now my site allows multiple identities (i.e. Facebook, Twitter, Flickr, etc.)
and I needed a single management point. I have a table that stores the token
information for each platform.
When a user authenticates on Yii, the <b>loadIdentityStates()</b>
method is called. I've overriden this method to also call my
<b>loadPlatformIdentities()</b> method.
This looks up my tokens from the database and pre-loads them into the various
platform objects like Twitter:

~~~
[php]
	Yii::app()->twitter->loadData(Yii::app()->twitter->loadData(
'user_id', 'screen_name', is_authenticated, array( 'oauth_token' =>
oauth_token, 'oauth_token_secret' => oauth_token_secret ) );
~~~

Once you make that call, you're all set to use the Twitter API! 

# StepStep 4: Make Twitter API Calls! #
-------------------------------
Now you've got it all set up, all you need to do is make a call to the Twitter
API. The CPSTwitterApi object handles all the nasty OAuth token passing and
whatnot to let you concentrate and retrieving and using Twitter data.
Almost all of the Twitter API functions have been converted to single methods in
the CPSTwitterApi class. Have a look-see through there and you'll see all the
calls you can make. 
Some of the Twitter API calls have the following three parameters: an 'id', a
user's 'user_id', or a screen name. Most of these calls require that you supply
ONE of the three values. You already have user_id and screen_name. The first
'id' is for use with the Twitter Search API. This API is actually a second
separate API and the 'id' values returned from that API do not jive with the
'user_id' values from the non-search API. Confusing, yes. They're working on
fixing it. Many calls default to the id of the authenticating user (i.e. the
user who's token you're using).

The way we created our component in the main.php configuration file, all data
returned to you from CPSTwitterApi will be in an associative array. I like it
that way. You can change the 'format' parameter in the configuration file to
either 'json', 'xml' or 'array'. The data will be returned to you in that
format. I find arrays easiest to deal with in PHP.

So, here's a sample call I made to get mentions of my Twitter account:

~~~
[php]

	$_arResults$_arResults =
Yii::app()->twitter->getMentions();
	echo
echo var_export( $_arResults, true );
~~~

Produces:

~~~
[php]

array (
  0 => 
  stdClass::__set_state(array(
     'text' => '@jablan Hah, couldn\'t be further from.',
     'in_reply_to_user_id' => 14147388,
     'user' => 
    stdClass::__set_state(array(
       'followers_count' => 81,
       'profile_image_url' =>
'http://s3.amazonaws.com/twitter_production/profile_images/53267682/april2008_2_normal.jpg',
       'description' => 'I make interesting things work in interesting ways
for the benefit of interesting people.',
       'utc_offset' => -21600,
       'profile_sidebar_fill_color' => 'ffd7bd',
       'created_at' => 'Thu Apr 24 19:07:17 +0000 2008',
       'friends_count' => 92,
       'screen_name' => 'vanadium',
       'statuses_count' => 1272,
       'profile_sidebar_border_color' => '9e9e9e',
       'favourites_count' => 4,
       'url' => 'http://www.op9.net/',
       'name' => 'Gary DuVall',
       'protected' => false,
       'profile_text_color' => '4d4d4d',
       'verified_profile' => false,
       'profile_background_image_url' =>
'http://s3.amazonaws.com/twitter_production/profile_background_images/2450081/background.jpg',
       'notifications' => NULL,
       'time_zone' => 'Central Time (US & Canada)',
       'profile_link_color' => '921611',
       'following' => NULL,
       'profile_background_tile' => true,
       'location' => 'Chicago, IL',
       'id' => 14516134,
       'profile_background_color' => 'ffffff',
    )),
     'created_at' => 'Thu Jun 11 22:24:47 +0000 2009',
     'favorited' => false,
     'in_reply_to_screen_name' => 'jablan',
     'truncated' => false,
     'id' => 2123032317,
     'in_reply_to_status_id' => 2122567595,
     'source' => 'web',
  )),
<b>...</b>
)
~~~

# WrappingWrapping it up! #
---------------
So you should be well on your way to geeking with Twitter and Yii now. If I've
left anything out or if you're confused or my writing sucks, please let me know.
I love feedback! jablan 'at' pogostick.com or PM me here.

Write new article
  • Written by: lucifurious
  • Updated by: wei
  • Category: Tutorials
  • Yii Version: 1.1
  • Votes: +4 / -1
  • Viewed: 20,301 times
  • Created on: Jun 11, 2009
  • Last updated: Oct 25, 2010
  • Tags: twitter