Flickr Gallery without fopen
Problem
Last week I set up the Flickr Gallery for our new WordPress blog.
I experienced a problem with the fopen commands which are heavily used by the flickr plugin. My webhoster has disabled allow_url_fopen for security reasons. So I had to find a way around it.
Solution
I patched the current FlickrGallery-plugin in version 0.7. You can download my patched plugin file here: flickr-gallery.php (ZIP). Replace your old one in the plugins dir with this one and see below what has changed.
Use socket connection
When allow_url_fopen enabled one has to use socket connections using fsockopen. In the online php manual I found a good code fragment that fetches an URL and returns the content without the HTTP header. Here is the function, modified a bit:
function fetchURL( $url ) {
$url_parsed = parse_url($url);
$host = $url_parsed["host"];
$port = $url_parsed["port"];
if ($port==0)
$port = 80;
$path = $url_parsed["path"];
//if url is http://example.com without final "/"
if (empty($path))
$path="/";
if ($url_parsed["query"] != "")
$path .= "?".$url_parsed["query"];
$out = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n";
$fp = fsockopen($host, $port, $errno, $errstr, 5);
if (!$fp) {
return false;
} else {
fwrite($fp, $out);
$body = false;
while (!feof($fp)) {
$s = fgets($fp, 1024);
if ( $body )
$in .= $s;
if ( $s == "\r\n" )
$body = true;
} }
fclose($fp);
return $in;
}
Replacement 1
There are two occurrences of fopen that must be replaced by the fetchURL function. Since fopen returns a resource but the fetchURL function returns a string some more lines have to be replaced:
This is the old code from line 503-519:
$f = @fopen($file,"r"); // Open remote source file
if (!$f) // Remote file couldn't be opened
{
return @file_get_contents ($cache_filename); // Return the file contents form the cache
}
$f2 = @fopen($cache_filename,"w+"); // Open local cache file
while ($r = @fread($f,8192)) // Loop through remote source file
{
@fwrite($f2,$r); // Write to the local cache
}
@fclose($f2);
@fclose($f);
Replace it with the following lines:
$f = fetchURL($file); // Open remote source file
if (!$f) // Remote file couldn't be opened
{
return @file_get_contents ($cache_filename); // Return the file contents form the cache
}
$f2 = @fopen($cache_filename,"w+"); // Open local cache file
@fwrite($f2,$f); // Write to the local cache
@fclose($f2);
@fclose($f);
Replacement 2
The second occurrences of fopen has is also used to read the EXIF meta data in a traffic limiting way, by reading only the first x bytes. My own patch always reads the whole file - but it should not be to difficult to modify this one.
This is the old code from line 549-565:
$f1 = @fopen($source, 'r'); // File to copy from (remote)
$f2 = @fopen($dest, 'w+'); // File to copy to (local)
$count = 0; // Initialize KB counter
while ($r = @fread($f1, 8192)) // Loop through and read 1 KB from source file each time
{
@fwrite($f2, $r); // Write the 1 KB to the dest file
$count++; // Increment KB counter
if (($kbytes != 0) && ($count == $kbytes)) // If we wanted to only download the partial file check to see if we've met the limit
{
break; // Break out of the while loop if we are at the limit
}
}
@fclose($f1); // Close source file
@fclose($f2); // Close dest file
Replace it with the following lines:
$f1 = fetchURL($source); // File to copy from (remote) $f2 = @fopen($dest, 'w+'); // File to copy to (local) @fwrite($f2, $f1); // Write the 1 KB to the dest file @fclose($f1); // Close source file @fclose($f2); // Close dest file
