Home arrow PHP arrow Error Handling for Dynamic Twitter Signature Images with PHP

Error Handling for Dynamic Twitter Signature Images with PHP

Over the course of my past two articles I’ve been showing you how to build a script capable of creating and displaying a dynamic signature image containing the latest status from a user’s Twitter feed. In the third installment in this series, I will be demonstrating how to add proper object-oriented error handling to the SignatureImage class.

TABLE OF CONTENTS:
  1. Error Handling for Dynamic Twitter Signature Images with PHP
  2. Understanding error-handling
  3. Throwing exceptions for errors
  4. Playing throw and catch
By: Nilpo
Rating: starstarstarstarstar / 1
August 25, 2009

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Before we begin, let’s take a moment to examine the fully operational class.

class SignatureImage

{

    private $screen_name;

    private $profile_image;

    private $status_text;

    private $local_avatar;

   

    public function __construct($name, $bg_image, $adir)

    {

        $this->fetchUserInfo(strtolower($name));

        $this->fetchAvatar($this->profile_image, $adir);

        $this->renderImage();

    }

 

    private function fetchUserInfo($name)

    {

        $url = "http://twitter.com/statuses/user_timeline/{$name}.xml?count=1";

        $xml = $this->curlRequest($url);

        if ($xml === false) {

            // User feed unavailable.

        }

        $statuses = new SimpleXMLElement($xml);

        if (!$statuses || !$statuses->status) {

            // Invalid user channel.

        }

       foreach ($statuses->status as $status) {

            $this->status_text   = (string) $status->text;

            $this->profile_image = (string) $status->user->profile_image_url;

            $this->screen_name   = (string) $status->user->screen_name;

            break;

        }

    }

 

    private function curlRequest($url)

    {

        if (!extension_loaded('curl')) {

            // PHP extension CURL is not loaded.

        }

        $curl = curl_init($url);

        curl_setopt($curl, CURLOPT_HEADER, false);

        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

        $result = curl_exec($curl);

        if (curl_errno($curl) !== 0 || curl_getinfo($curl, CURLINFO_HTTP_CODE) !== 200) {

            $result === false;

        }

        curl_close($curl);

        return $result;

    }

 

    private function fetchAvatar($url, $adir)

    {

        $parts      = explode('/', $url);

        $fname      = end($parts);

        $adir       = preg_match('#^(.*?)/$#i', $url) ? $adir : "{$adir}/";

        $fname      = $adir . $fname;

        if (!file_exists($fname)) {

            $img = $this->curlRequest($url);

            $fp = fopen($fname, 'w');

            fwrite($fp, $img);

            fclose($fp);

        }

        $this->local_avatar = $fname;

    }

}

 

    private function renderImage($bg_image)

    {

        if (!function_exists('gd_info')) {

            // No GD support.

        }

        $margin_left = 11;

        $margin_bottom = 6;

        $image = @imagecreatefromjpeg($bg_image);

        if (!$image) {

            // Unable to create image.

        }

        $this->embedAvatar($image, $this->local_avatar, $margin_left, $margin_bottom);

        $string = "{$this->screen_name}: {$this->status_text}";

        $this->embedText($image, $string, $margin_left, $margin_bottom);

        header("Content-type: image/jpeg");

        $created = @imagejpeg($image);

        if (!$created) {

            // Unable to finalize image.

        }

        @imagedestroy($image);

    }

 

    private function embedAvatar(&$image, $avatar, $left, $bottom)

    {

        if (file_exists($avatar)) {

            if (stristr($avatar, '.jpg')) {

                $aimg = @imagecreatefromjpeg($avatar);

            } elseif (stristr($avatar, '.png')) {

                $aimg = @imagecreatefrompng($avatar);

            }

            if (!$aimg) {

                // Unable to create avatar.

            }

            $awidth  = imagesx($aimg);

            $aheight = imagesy($aimg);

            $top     = imagesy($image) - $aheight - $bottom;

            $copied  = @imagecopy($image, $aimg, $left, $top, 0, 0, $awidth, $aheight);

            if (!$copied) {

            // Unable to add avatar to image.

            }

        }

    }

 

    private function embedText(&$image, $text, $left, $top, $tmaxw=300, $font=3)

    {

        $fheight = imagefontheight($font);

        $color   = imagecolorallocate($image, 100, 100, 100);

        $lines   = $this->lineWrap($font, $text, $tmaxw);

        $lmax    = floor(imagesy($image) / $fheight);

        $lcount  = (count($lines) > $lmax) ? $lmax : count($lines);

        $ttop    = (imagesy($image) - ($lcount*$fheight)) / 2;

        $tleft   = 2*$left + 48;

        while ((list($num, $line) = each($lines)) && $num < $lcount) {

            imagestring($image, $font, $tleft, $ttop, $line, $color);

            $ttop += $fheight;

        }

    }

 

    private function lineWrap($font, $text, $maxwidth)

    {

        $fwidth  = imagefontwidth($font);

        if ($maxwidth != NULL) {

            $maxcharsperline = floor($maxwidth / $fwidth);

            $text = wordwrap($text, $maxcharsperline, "n", 1);

        }

        return explode("n", $text);

    }

}

 

isset($_GET['name']) or die('You must provide a user name.');

 

new SignatureImage($_GET['name'], 'banners/my_banner.jpg', 'avatars', 'cache');

This class already employs pretty thorough error-catching.  Throughout the code I’ve used comments to indicate error states.  Today we’ll be replacing those comments with actual error-handling code in order to make this a fully functional OOP class.



 
 
>>> More PHP Articles          >>> More By Nilpo
 

blog comments powered by Disqus
   

PHP ARTICLES

- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...
- PHP: Building Concrete Validators
- Sanitizing Input with PHP
- Executing Shell Commands with PHP
- Handling File Data with PHP
- File Security and Resources with PHP
- ArrayObject PHP Class Examples
- ArrayObject PHP Class: An Introduction
- Getting File System Data with PHP
- PHP Tools for Working with the File and Oper...
- Working with the File and Operating System w...
- PHP Proxy Patterns: Completing a Blog


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 8 - Follow our Sitemap

Dev Shed Tutorial Topics: