Advertisement
PHP

How to Update your Twitter Status with CodeIgniter

by

Hi, in this tutorial we will update our twitter status via the 'Twitter API' using CodeIgniter. I recommend following step by step, rather than glossing over the tutorial. Let's dig in!

Tutorial Details

  • Program: CodeIgniter PHP Framework
  • Version: 1.7.1
  • Difficulty: Advanced
  • Estimated Completion Time: 30 minutes

1. Configuring CodeIgniter

At first we need to edit some default settings within the CI config section.

Open the system/application/config/autoload.php and edit the following from:

$autoload['libraries'] = array('');

to:

$autoload['libraries'] = array('database');

This will autoload the database. Next, open database.php and edit the database connection setting - the name of
your database, user and password. As name we will be using ci_twitter_api.

Now open config.php and change the base_url to your CI folder. My folder is called twitter_api.
In that folder is my system folder. So my base_url will be:

$config['base_url']	= "http://localhost/ci/twitter_api";

2. Filling the Database

Because we are going to work with a database, we will need some data to play with. Open phpmyadmin or your
favorite database management tool and create a new database called ci_twitter_api. Now we will set up a
new table using the following SQL query, but attention, use YOUR twitter username and password credentials.

CREATE TABLE IF NOT EXISTS `accounts` (
     `id` int(11) NOT NULL AUTO_INCREMENT,
     `username` varchar(120) NOT NULL,
     `password` varchar(32) NOT NULL,
     `active` int(11) NOT NULL,
     `last_message` varchar(140) NOT NULL,
     PRIMARY KEY (`id`)
   ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
   
   INSERT INTO `accounts` (`id`, `username`, `password`, `active`, `last_message`) VALUES
   (1, 'YOUR USERNAME', 'YOUR PASSWORD', 1, 'No message sent.');

Click the OK button on the right side and the query should be processed. Now your structure for the table
accounts should look similar to the image below.

3. Building the Model

Go to system/application/models and create a new file called twitter_model.php.

First, we'll declare two global variables at the top.

var $accounts_table = 'accounts';
var $update_url = 'http://twitter.com/statuses/update.xml';

So $accounts_table refers to the table we created just before, and $update_url is the url we will be using
to update our status. If Twitter changes their update URL, you only need to edit it one time here instead of every time its used in the code.

Now we will create our first method which will simply return the active user account stored in the database,
based on the row active and value 1. I have added this because some people have two or more Twitter
accounts.

 class Twitter_model extends Model {

    // get the active twitter account from the database, by row active = 1
    function getActiveAccount()
    {
        return $this->db->get_where($this->accounts_table, array('active' => '1'))->row();	
    }

We are simply using active records
to retrieve the active account and return the affected row.

Next step, we are going to build the main method, the update method. This will use our
username, password and of course the message we want to send and update our status on Twitter. Apart from that,
it will interpret the HTTP_CODE which is returned by Twitter for telling us if the status was updated
successfully or not.

// update twitter status and last message on success
function update_status($username, $password, $message)
{
	$ch = curl_init($this->update_url);

	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, 'status='.urlencode($message));
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_USERPWD, $username . ':' . $password);
	
	curl_exec($ch);
	
	$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	
	// if we were successfull we need to update our last_message
	if ($httpcode == '200')
	{
		$this->db->where('active', '1');
		$this->db->update($this->accounts_table, array('last_message' => $message));
		
		return TRUE;	
	}
	
	else
	{
		return FALSE;	
	}
}

At first view the code above may look a bit complicated but it's not that hard to understand. The most important part is
that we use cURL to communicate with Twitter. It's a really great
library which allows us to send and receiveHTTP POST data from Twitter.

Now then curl_init initializes a cURL session and takes the URL as a parameter - in our case the status update
URL from the Twitter API.

With curl_setopt we set some necessary options for the cURL transfer.

  • CURLOPT_POST: We set this to '1' to use HTTP POST, which is the same as used in HTML forms.
  • CURLOPT_POSTFIELDS: This options aceepts the POST Data that we want to send. In our case
    'status=' and our message. We need to urlencode the message to be able to use special
    characters like '%&/" .
  • CURLOPT_RETURNTRANSFER: Its important for us to set this to '1' because it will return the transfer
    as a string. That string will later tell us if the status was updated successfully or not.
  • CURLOPT_USERPWD: This option is for authentication. It simply takes our twitter username and password
    in the format username:password.
curl_exec($ch);

$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// if we were successfull we need to update our last_message
if ($httpcode == '200')
{
	$this->db->where('active', '1');
	$this->db->update($this->accounts_table, array('last_message' => $message));
	
	return TRUE;	
}

else
{
	return FALSE;	
}

In this part we are executing the transfer with curl_exec() and retrieving the returned HTTP_CODE
using curl_getinfo(CURLINFO_HTTP_CODE). This HTTP_CODE tells us if the status update was completed or not.
Code '200' means it worked and the update was done. You can view a complete list of HTTP status codes
here.

If we get '200' returned by Twitter, we send a query to our database which updates our last_message row, and finally
we return TRUE. If 200 is not returned, we simply return FALSE.

To finish our twitter_model we will create one last method which will get the last message we sent. We need
this method because we will display our most recent message in a view.

// get the last_message, by row active = 1
function getLastMessage()
{
	$this->db->select('last_message');
	$last_message =  $this->db->get_where($this->accounts_table, array('active' => '1'))->row()->last_message;
	
	return htmlspecialchars($last_message);
}

This method is pretty simple. It selects the last_message row from our active account and returns it
converted with htmlspecialchars to HTML entities.
Our twitter_model.php now looks like this:

	class Twitter_model extends Model {
	
	var $accounts_table = 'accounts';
	var $update_url = 'http://twitter.com/statuses/update.xml';
	
	// get the active twitter account from the database, by row active = 1
	function getActiveAccount()
	{
		return $this->db->get_where($this->accounts_table, array('active' => '1'))->row();	
	}
	
	// update twitter status and last message on success
	function update_status($username, $password, $message)
	{
		$ch = curl_init($this->update_url);

		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, 'status='.urlencode($message));
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_USERPWD, $username . ':' . $password);
		
		curl_exec($ch);
		
		$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		
		// if we were successfull we need to update our last_message
		if ($httpcode == '200')
		{
			$this->db->where('active', '1');
			$this->db->update($this->accounts_table, array('last_message' => $message));
			
			return TRUE;	
		}
		
		else
		{
			return FALSE;	
		}
	}
	
	// get the last_message, by row active = 1
	function getLastMessage()
	{
		$this->db->select('last_message');
		$last_message =  $this->db->get_where($this->accounts_table, array('active' => '1'))->row()->last_message;
		
		return htmlspecialchars($last_message);
	}
}

4. Building the Controller

Now go to system/application/controllers and create a new file called twitter.php.
Let's add some lines:

class Twitter extends Controller {

function Twitter()
{
	parent::Controller();
	
	$this->load->model('twitter_model');
}

This is a simple CI constructor which loads our twitter_model. So it will be available to us within the whole controller.
Now comes the index() method.

function index()
{
	$data['heading'] = 'Hi, send a tweet!';
	$data['last_message'] = $this->twitter_model->getLastMessage();
	$data['active_user'] = $this->twitter_model->getActiveAccount()->username;
	
	$this->load->view('header', $data);
	$this->load->view('index');
	$this->load->view('footer');
}

We are passing information like some text, our last message and the username of the active user to the $data array.
Thanks to our twitter_model it's a cinch to grab the last message and the active username. At least we are loading some
views which we will create after we finish our controller. Let's build the update method.

// updating our status on twitter ( new message )
function update()
{		
	if ($this->input->post('submit'))
	{
		$this->load->library('form_validation');
		$this->form_validation->set_error_delimiters('<div class="error">', '</div>');
		$this->form_validation->set_rules('message', 'Message', 'trim|required|min_length[5]|max_length[140]');
		
		if ($this->form_validation->run() == FALSE)
		{
			$this->index();
		}
		
		else
		{
			$message = $this->input->post('message');
			
			// get useraccount data
			$account = $this->twitter_model->getActiveAccount();
			$username = $account->username;
			$password = $account->password;
			
			// send a tweet
			if ($this->twitter_model->update_status($username, $password, $message))
			{
				redirect('twitter');	
			}
			
			else
			{
				$data['error'] = 'There was an error while updating your status';
				
				$this->load->view('header', $data);
				$this->load->view('error');
				$this->load->view('footer');
			}
		}
	}

This may be confusing again but we will go through it part by part.

if ($this->input->post('submit'))
	{
		$this->load->library('form_validation');
		$this->form_validation->set_error_delimiters('
', '
'); $this->form_validation->set_rules('message', 'Message', 'trim|required|min_length[5]|max_length[140]'); if ($this->form_validation->run() == FALSE) { $this->index(); }

With $this->input->post('submit') we check if the form was submitted - which we will create later in our main view
file. After that, we load the form_validation library because we want to ensure that certain inputs require some rules,
like a minimum and maximum length of 5 and 140 characters. Additionally we are trimming off the whitespace with trim and
setting the field as required because we don't need an empty message. The function set_rules takes, as the first parameter,
the name of the from field, our case message (which will be created soon in the view) and as second parameter a human
the name for this field, which will be inserted into the error message ( will be done in the view file ).

We call $this->form_validation->run(), which can return TRUE or FALSE. If a rule we set was broken it
will return FALSE and we simply call our index() method. In the view files called by the index() method the
error messages will be displayed after we have created our views.

else
   {
       $message = $this->input->post('message');
       
       // get useraccount data
       $account = $this->twitter_model->getActiveAccount();
       $username = $account->username;
       $password = $account->password;
       
       // send a tweet
       if ($this->twitter_model->update_status($username, $password, $message))
       {
           redirect('twitter');	
       }
       
       else
       {
           $data['error'] = 'There was an error while updating your status';
           
           $this->load->view('header', $data);
           $this->load->view('error');
           $this->load->view('footer');
       }
   }

Thanks to our twitter_model, again it's so easy to retrieve the username and the password of the current active user.
We could also do $username = $this->twitter_model->getActiveAccount()->username but I think for this tutorial this is
a little bit easier to understand.

Using $this->twitter_model->update_status() we call the method that will "talk" to Twitter. It tells Twitter our
username, password and our message. If the status was updated successfully, we redirect, using redirect() from the url helper.

If something was wrong, we set an error message and load some view files, which will be created in the next step :).
The Controller looks now like this:

	class Twitter extends Controller {

	function Twitter()
	{
		parent::Controller();
		
		$this->load->model('twitter_model');
	}
	
	function index()
	{
		$data['heading'] = 'Hi, send a tweet!';
		$data['last_message'] = $this->twitter_model->getLastMessage();
		$data['active_user'] = $this->twitter_model->getActiveAccount()->username;
		
		$this->load->view('header', $data);
		$this->load->view('index');
		$this->load->view('footer');
	}
	
	// updating our status on twitter ( new message )
	function update()
	{		
		if ($this->input->post('submit'))
		{
			$this->load->library('form_validation');
			$this->form_validation->set_error_delimiters('
', '
'); $this->form_validation->set_rules('message', 'Message', 'trim|required|min_length[5]|max_length[140]'); if ($this->form_validation->run() == FALSE) { $this->index(); } else { $message = $this->input->post('message'); // get useraccount data $account = $this->twitter_model->getActiveAccount(); $username = $account->username; $password = $account->password; // send a tweet if ($this->twitter_model->update_status($username, $password, $message)) { redirect('twitter'); } else { $data['error'] = 'There was an error while updating your status'; $this->load->view('header', $data); $this->load->view('error'); $this->load->view('footer'); } } } else { redirect('twitter'); } } }

5. Creating the Views

Now we will create our view files. Go to system/application/views and create the following files:

  • header.php
  • footer.php
  • index.php
  • error.php

The header.php will contain the basic html meta information, our CSS link, and the opening tags of our main divs,
#wrapper and #main.

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <link media="screen" rel="Stylesheet" type="text/css" href="<?php echo base_url(); ?>css/style.css" />
    <title>Using the Twitter API with CodeIgniter</title>
    </head>
    
    <body>
    
    <div id="wrapper">
    
    <div id="main">

We are using base_url() which we configured to reference our CSS file, which will be created in the next step.

The footer.php simply contains our closing tags.

	</div><!--end main-->

    </div><!--end wrapper-->
    
    </body>
    </html>

The index.php is where the party goes.

	<h3>
	<?php echo $heading; ?>
    <span>
    	( account: <?php echo anchor('http://twitter.com/' . $active_user, $active_user); ?> )
    </span>
    </h3>
    
    
    <?php echo form_error('message'); ?>
    
    <?php echo form_open('twitter/update', array('id' => 'update_form')); ?>
    <?php echo form_input(array('name' => 'message', 'maxlength' => '140')); ?>
    <?php echo form_submit('submit', 'update'); ?>
    <?php echo form_close(); ?>
    
    <div id="last_message">
        <fieldset>
            <legend>Last <span>sent by <b><?php echo $active_user ?></b></span></legend>
            <p><?php echo $last_message; ?></p>
        </fieldset>
    </div>

All variables used here are passed through the index() method from our controller. In addition to that,
we are using the form helper to create a simple html form. Remember, I told you the error handling for the
message field will be done here; form_error('message') is doing that magic.

Below the form we are displaying the last message sent by the active user's account.

Finally the error.php will be used for a custom error file in case the status update was unsuccessful.

	<h3><?php echo $error; ?></h3>

     <?php echo anchor('twitter', 'Go back and try again'); ?>

6. Adding some CSS

To make it a bit prettier, we will add some CSS. Go to system/
and create the folder css. Inside of that folder create a file called style.css and insert
the following code.

    /* Reset CSS */
    
    html, body, div, span, object, h1, h2, h3, h4, h5, h6, p, blockquote, pre,
    a, address, code, img, 
    small, strong, dl, dt, dd, ol, ul, li,
    fieldset, form, label {
        margin: 0;
        padding: 0;
        border: 0;
        outline: 0;
        font-size: 100%;
        vertical-align: baseline;
        background: transparent;
    }
    
    body {
    	line-height: 1.5;
        font-family:Arial, sans-serif;
        margin:0;
    }
    ol, ul, li {
        list-style: none;
        list-style-type:none;
    }
    
    .clear { clear:both; }
    
    /* DEFAULTS */
        
    h3 {
        color:#35CCFF;
        font-size:20px;
    }

    /* CUSTOM */
        
    #wrapper {
        width:900px;
        margin:0 auto;
    }
    
    /* main */
    
    #main {
        margin-top:50px;
    }
    
    #main h3 span {
        font-size:14px;	
        color:#cccccc;	
    }
    
    #main h3 a {
        color:#cccccc;	
    }
    
    /* form */
    
    #update_form input {
        width:888px;
        padding:5px;
        border:1px solid #d3d3d3;
        display:block;
    }
    
    #update_form input[type="submit"] {
        width:auto;
        margin-top:10px;
        background-color:#000000;;
        border:none;
        color:white;
        font-size:12px;
        font-weight:bold;
        cursor:pointer;
        padding:3px;
    }
    
    div.error {
        display:block;
        background-color:#FB8A8A;
        border:1px solid #FF3B3B;
        padding:5px;
        color:#ffffff;
        width:50%;
        margin-bottom:30px;
        font-weight:bold;
        margin:0 auto 10px auto;
        text-align:center;
    }
    
    /* last message */
    
    #last_message fieldset {
        border:1px dashed #d3d3d3;
        padding:5px;
        margin-top:30px;
    }
    
    #last_message fieldset p {
        padding:5px;
        font-size:18px;
        font-weight:normal;
    }
    
    #last_message legend span {
        font-size:12px;
    }

I am using Eric Meyers CSS reset to neutralize the view on all browsers. Your application should now likebthe image below.

The Big Finale

Let's test our fresh application. We'll drop a message and press the update button!

After the update was made:

Lets take a look at Twitter :)

if we are violating a form validation rule by trying to send an empty message:

Conclusion

I really hope that I helped you a little bit with learning CodeIgniter and how to use the great Twitter API! Would you have done anything differently? If so, let us know!


Related Posts