Posts tagged "code"

Solving the “break-out” issue in iFrame Facebook applications

I’ve tinkered with Facebook apps enough to find out what works and what doesn’t. The most frustrating things I’ve had to deal with is when I’ve developed a Facebook app in an iframe. Using the canvas page rather than an iframe is great. You’ll encounter little to no weirdness. But if you’re like me, you want full control over your app, and that’s accomplished by going the iframe route.

Probably the single most frustrating thing about using the iframe is the “break-out” problem. Basically when a user visits your application, they are suddenly thrown out of Facebook completely into a new window and all sorts of crazy things can happen from there, the least of which are some errors displaying on the page, or the app doesn’t work. The worst I’ve seen is when a new window opens with the application inside and the browser window begins shrinking until it becomes nothing greater than a 20 x 20 pixel box. Closing the browser, well.. closes it. But when you reopen your browser it is the same small size. This is just unacceptable, and frankly it’s embarrasing for the developer.

So, how to solve it?

After weeks of avoiding the issues, and finally hours of surfing the net I came across a genius snippet of code, miracle code in fact. The following code will help those of you out there with some experience in writing Facebook apps. As for the rest of you… you’re SOL, for the moment. I plan on writing a few tutorials in the future that show how to develop Facebook applications.

function get_facebook_vars() {
    $fbvars = "";
    foreach ($_GET as $key=>$value) {
        if (strpos($key, "fb_sig") !== false) {
            $fbvars .= "$key=$value&";
        }
    }
    if ( empty($fbvars)) {
        return false;
    }
    return $fbvars;
}
 
// IMPORTANT!
// There have been instances where the iframe has broken out of the Facebook application.  This is BAD!
// We must be sure that we have all the needed junk in the querystring from FB,
// and if we don't then we redirect to the FB app page
$fbvars = get_facebook_vars();
 
if ($fbvars !== false) {
 
    // Include the Facebook API file.  You can download this from the developers section of FB.
    require_once ("facebook.php");
 
    // Create a Facebook object
    $facebook = new Facebook($key, $secret);
 
    // Attempt to get a logged in user id.
    // This will redirect us to the FB login page if the user is not logged in.
    $user = $facebook->require_login();
 
}


The SimpleImage Class

In a previous tutorial we learned how to upload an image using HTML and PHP. Now we will talk some about the image functions built into PHP, specifically how they can be used to resize and save images.

Let’s say the users on your website can upload their profile picture. You might be able to get by with one image only. Or, you can save 2 or 3 different sized versions of the image, to be used in different parts of your site. For example, you may want a thumbnail of the profile picture to show in a list of users. And you may want a second medium sized image to display on the user’s profile page. Finally, a large version of the image could be displayed when a user clicks the medium sized picture, to give them a close up view.

To accomplish this we’ll use some of PHP’s image functions and wrap them up in nice neat package that we’ll call the SimpleImage class.

Copy and paste the following code into a new PHP file.

<?php 
class SimpleImage {
 
    var $image;
    var $image_type;
 
    function isValidImage() {
        if (imagesx($this->image) !== false) {
            return true;
        } else {
            return false;
        }
    }
 
    function load($filename) {
        $image_info = getimagesize($filename);
        $this->image_type = $image_info[2];
        if ($this->image_type == IMAGETYPE_JPEG) {
            $this->image = imagecreatefromjpeg($filename);
        } elseif ($this->image_type == IMAGETYPE_GIF) {
            $this->image = imagecreatefromgif($filename);
        } elseif ($this->image_type == IMAGETYPE_PNG) {
            $this->image = imagecreatefrompng($filename);
        }
    }
    function save($filename, $image_type = IMAGETYPE_JPEG, $compression = 75, $permissions = null) {
        if ($image_type == IMAGETYPE_JPEG) {
            imagejpeg($this->image, $filename, $compression);
        } elseif ($image_type == IMAGETYPE_GIF) {
            imagegif($this->image, $filename);
        } elseif ($image_type == IMAGETYPE_PNG) {
            imagepng($this->image, $filename);
        }
        if ($permissions != null) {
            chmod($filename, $permissions);
        }
    }
    function output($image_type = IMAGETYPE_JPEG) {
        if ($image_type == IMAGETYPE_JPEG) {
            imagejpeg($this->image);
        } elseif ($image_type == IMAGETYPE_GIF) {
            imagegif($this->image);
        } elseif ($image_type == IMAGETYPE_PNG) {
            imagepng($this->image);
        }
    }
    function getWidth() {
        return imagesx($this->image);
    }
    function getHeight() {
        return imagesy($this->image);
    }
    function resizeToHeight($height) {
        $ratio = $height / $this->getHeight();
        $width = $this->getWidth() * $ratio;
        $this->resize($width, $height);
    }
    function resizeToWidth($width) {
        $ratio = $width / $this->getWidth();
        $height = $this->getheight() * $ratio;
        $this->resize($width, $height);
    }
    function scale($scale) {
        $width = $this->getWidth() * $scale / 100;
        $height = $this->getheight() * $scale / 100;
        $this->resize($width, $height);
    }
    function resize($width, $height) {
        $new_image = imagecreatetruecolor($width, $height);
        imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
        $this->image = $new_image;
    }
}
 
?>

Now we need to call the methods of our class to perform some resizing. Copy and paste the following code below your class:

 
// The directory where our images will be stored
$file_directory = "images/users/1/";
 
// The path to the original image file on our web server
$original_file_path = $file_directory . "profile.jpg";
 
// Save a large version of the image that is no wider and no taller than 600 pixels
$image = new SimpleImage();
$image->load($original_file_path);
if($image->getWidth() > 600){
	$image->resizeToWidth(600);
}
if($image->getHeight() > 600){
	$image->resizeToHeight(600);
}
$image->save($file_directory."profile_600x600.jpg");
 
// Create a medium sized version no wider and no taller than 300 pixels
$image = new SimpleImage();
$image->load($original_file_path);
if($image->getWidth() > 300){
	$image->resizeToWidth(300);
}
if($image->getHeight() > 300){
	$image->resizeToHeight(300);
}
$image->save($file_directory."profile_300x300.jpg");
 
// Create a thumbnail version no wider and no taller than 60 pixels
$image = new SimpleImage();
$image->load($original_file_path);
if($image->getWidth() > 60){
	$image->resizeToWidth(60);
}
if($image->getHeight() > 60){
	$image->resizeToHeight(60);
}
$image->save($file_directory."profile_60x60.jpg");

When our file is executed it will save 3 differently sized images, small, medium, and large, from the one original image.


How to upload a file using PHP

One of the cool things about server side scripting is the ability to upload files from a user’s computer to your web server. In this tutorial I will demonstrate PHP’s ability to capture uploaded files and save them on the web server. Our sample takes a user’s photo and saves it to a folder on the server where other users can view it on the web.

You can download the code here.

Create a file with a name of your choice and put the following code into it.

<form action="upload.php" method="post" enctype="multipart/form-data">
	<div>Upload your photo:</div>
	<input type="file" name="photo_file" />
	<input type="submit" name="submit" value="Upload" />
	<input type="hidden" name="max_file_size" value="8000000" />
	<input type="hidden" name="user_id" value="1" />
</form>

This is the web page where the user can select the file they want to upload.

The first line has two parts I want to point out: the action attribute and the enctype attribute. The action‘s value is the name of your PHP file that will handle the upload. The entype‘s value in this case tells our server that we aren’t just posting your typical text or password type values, but rather we are passing several types, namely a file and a few inputs.

The only required types of inputs for uploading a file are file and submit, but for this example I’ve added a hidden user_id that will be used as well.

Now, on to the juicy stuff… handling the upload on the server.

Create a file called upload.php. This file has the same name that we gave our form’s action attribute. When you are coding your own application you can use whatever file name you want.

Put the following code into your upload.php file:

<?php
 
// Make sure the uploaded file is an image of type JPG, GIF, or PNG and that it does not exceed 8000000 bytes (approx. 8 MB) in size.
if (
!empty($_FILES["photo_file"]["tmp_name"]) &&
$_FILES["photo_file"]["size"] < 8000000 &&
(
	$_FILES["photo_file"]["type"] == "image/gif" ||
	$_FILES["photo_file"]["type"] == "image/jpeg" ||
	$_FILES["photo_file"]["type"] == "image/pjpeg")
)
{
 
    // The file has already been saved to a temporary location on the server.  Get the temp file's path.
    $file_path = $_FILES['photo_file']['tmp_name'];
 
    // Grab the User ID we sent from our form
    $user_id = $_POST['user_id'];
 
    // Create the directory where our user photos where be stored, if it doesn't already exist.
    // We will give our directory name the ID of the user that uploaded the photo.
    $save_dir = "img/users/$user_id";
	if (!file_exists($save_dir)) {
 
		// Our directory does not already exists, so create it.
        mkdir($save_dir, 0755, true);
	}
 
    // Attempt to move the temp file to our user's folder.
	$save_file_path = $save_dir . "/" . basename($_FILES['photo_file']['name']);
    if (move_uploaded_file($_FILES['photo_file']['tmp_name'], $save_file_path)) {
 
        // Moving the file was a success!
        echo("<div>Your photo has been uploaded successfully!</div><div><img src="$save_file_path" />");
 
    } else {
 
        // Moving the file failed.  Prompt the user to try again.
        echo("There was an error uploading your file.  Please try again.");
 
    }
}
 
?>

What does all this do? In a nutshell:

  • Verifies that the uploaded image is of JPEG, GIF, or PNG type.
  • Saves the file to a folder named after the User ID on the server.
  • If successful the picture is displayed on the page for the user to see!

Fun stuff huh! In a later tutorial I will show you how to resize your uploaded images, creating thumbnails, medium sized, and large images.