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