Created
October 1, 2009 20:09
-
-
Save eethann/199208 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* when twitpic URL is found in filtered $text, download the image file | |
* - use curl to get info from API on actual URL (w/ temporary auth key) | |
* - then use that URL to download the file to local $dl_dir | |
* @return downloaded file path or FALSE | |
*/ | |
function _twitpic_filter_download_twitpic($pic_code) { | |
$pic_url = 'http://twitpic.com/show/full/' . $pic_code; | |
// get download directory | |
$dl_dir = variable_get('twitpic_filter_images_dir', file_directory_path()); // set in filter config | |
$dl_dir = trim($dl_dir, '\\/'); // clear trailing slash | |
// does the file already exist / already downloaded? | |
// PROBLEM: we don't know the file type at this point! only known from the API call... | |
// but don't want to run API call every time a pic is shown... | |
// workaround: the file convention is 'twitpic_CODE.TYPE' in $dl_dir - so look for 'twitpic_CODE.*' | |
// THIS ASSUMES PIC CODES ARE UNIQUE... THEY SHOULD BE, SINCE THAT'S ALL THAT ID'S THEM... | |
$check_exists = glob($dl_dir . '/twitpic_'.$pic_code.'*'); | |
// (checking pattern from relative dir not realpath(), should be ok; otherwise have to strip prefix) | |
watson_debug($check_exists, 'check ' . realpath($dl_dir) . '/twitpic_'.$pic_code.'*'); | |
if (!empty($check_exists)) { // at least 1 file exists | |
// weird scenario w/ >1 file found, shouldn't happen, but track just in case | |
if (sizeof($check_exists) > 1) { | |
drupal_set_message("More than one Twitpic file matching code {$pic_code} exists", 'warning'); | |
watchdog('twitpic_filter', 'More than one Twitpic file matching code {$pic_code} exists: ' . watson_debug($check_exists,'',false), WATCHDOG_WARNING); | |
} | |
// path should now be in same format as if downloaded new | |
return array_shift($check_exists); | |
} | |
// doesn't exist yet... | |
// GET FILE INFO (ESP TYPE), THEN DOWNLOAD | |
$ch = curl_init($pic_url); | |
// (set these opts thru trial and error) | |
curl_setopt_array($ch, array( | |
CURLOPT_BINARYTRANSFER => 1, | |
CURLOPT_RETURNTRANSFER => 0, | |
CURLOPT_HEADER => 0, | |
CURLOPT_FOLLOWLOCATION => 1, // follow redirects - key! | |
CURLOPT_TIMEOUT => 10, // too short? but don't want page to freeze b/c of this | |
CURLOPT_NOBODY => 1, // don't output anywhere | |
)); | |
curl_exec($ch); | |
$info = curl_getinfo($ch); // xml converted to array | |
//drupal_set_message("info for $pic_url:" . watson_debug($info, '', false)); // DEBUGGING | |
curl_close($ch); | |
// get file info | |
// actual URL will be returned w/ auth key | |
if (!isset($info['url'])) { | |
watchdog('twitpic_filter', 'Unable to get file info for Twitpic #'.$pic_code, WATCHDOG_ERROR); | |
drupal_set_message('Twitpic Filter unable to get file info for Twitpic #'.$pic_code, 'error'); | |
return FALSE; | |
} | |
$pic_url = $info['url']; // actual | |
if (! preg_match('|/photos/full/([0-9]*)\.(.{3,4})\?|i', $info['url'], $info_matches)) { | |
watchdog('twitpic_filter', 'Returned URL for Twitpic #'.$pic_code.' not in expected format', WATCHDOG_ERROR); | |
drupal_set_message('Returned URL for Twitpic #'.$pic_code.' not in expected format', 'error'); | |
return FALSE; | |
} | |
// check file type | |
if (!isset($info_matches[2])) { | |
watchdog('twitpic_filter', 'No file type found for Twitpic #'.$pic_code, WATCHDOG_ERROR); | |
drupal_set_message('No file type found for Twitpic #'.$pic_code, 'error'); | |
return FALSE; | |
} | |
$file_type = strtolower($info_matches[2]); | |
// validate file type | |
// @TODO should these be set in admin form? | |
if (! in_array($file_type, array('jpg', 'jpeg', 'png', 'gif'))) { | |
watchdog('twitpic_filter', 'Invalid file type found for Twitpic #'.$pic_code, WATCHDOG_ERROR); | |
drupal_set_message('Invalid file type found for Twitpic #'.$pic_code, 'error'); | |
return FALSE; | |
} | |
// file type is good, download it... | |
// same convention as above -- see comment about file type | |
// (only now is file type known for sure) | |
$dl_file = $dl_dir . '/' . 'twitpic_'.$pic_code . '.' . $file_type; // relative to webroot | |
$dl_realpath = realpath($dl_file); // absolute | |
// running all these now w/ errors suppressed | |
// @TODO curl handle errors more gracefully? | |
@$ch = curl_init($pic_url); // reinitialize | |
@$fp = fopen($dl_realpath, "wb"); | |
@curl_setopt_array($ch, array( | |
CURLOPT_FILE => $fp, | |
CURLOPT_HEADER => 0, | |
CURLOPT_FOLLOWLOCATION => 1, | |
CURLOPT_TIMEOUT => 60, | |
)); | |
@curl_exec($ch); | |
@curl_close($ch); | |
@fclose($fp); | |
// @TODO handle permission error? | |
// make sure file not empty | |
if (!file_exists($dl_realpath) or !filesize($dl_realpath)) { | |
watchdog('twitpic_filter', "Attempted to download twitpic '$pic_code' to $dl_realpath, but file is missing or empty.", WATCHDOG_ERROR); | |
drupal_set_message("Attempted to download twitpic '$pic_code' to $dl_file, but file is missing or empty.", 'error'); | |
return FALSE; | |
} | |
drupal_set_message("Downloaded Twitpic '$pic_code' to $dl_file"); | |
return $dl_file; | |
} | |
/** | |
* passed $text from the filter 'processing', find Twitpic URLs and replace with images | |
* @param $text passed from filter 'process' $op | |
* @param $format passed from filter, for checking per-filter configs (imagecache preset, etc) | |
* @return $text for output (changed or unchanged) | |
*/ | |
function _twitpic_filter_put_pics($text, $format) { // called by 'process' $op of twitpic_filter_filter() | |
/** | |
* pattern: twitpic url w/ 5-digit code, not in html attribute (src or href), | |
* not w/ alphanumeric, slash, period, or quotations before or after | |
* (see testpattern.php) | |
*/ | |
$twitpic_pattern = '#(?<![\'".a-zA-Z0-9/])(http://twitpic.com/([a-zA-Z0-9]{5}))(?![\'".a-zA-Z0-9/])#im'; | |
if ($matchres===FALSE) { // regex ERROR | |
watchdog('twitpic_filter', 'Regex error', WATCHDOG_ERROR); | |
drupal_set_message('Regex error in Twitpic Filter.', 'error'); | |
return $text; | |
} | |
// technically there can only be 1 twitpic per tweet (preg_match), but allow for many (preg_match_all) for other uses | |
elseif (preg_match_all($twitpic_pattern, $text, $matches, PREG_SET_ORDER)) { | |
// watson_debug($matches, 'all matches'); | |
// $matches will be 2-D, each element having [0]=full match, [1]=URL, [2]=code (0=1 effectively) | |
foreach($matches as $match) { | |
// not sure if/when this scenario would occur, but check just in case | |
if (!isset($match[2])) { | |
watchdog('twitpic_filter', 'Twitpic match apparently found but missing code: ' | |
. '<pre>'.print_r($match,true).'</pre>', WATCHDOG_WARNING); | |
drupal_set_message('Twitpic Filter unable to find an image code.', 'error', false); | |
} | |
else { // code found | |
$replace = $match[1]; // URL to replace w/ image | |
$pic_code = $match[2]; // twitpic image code to look for | |
// Download file or use existing if already downloaded | |
$pic_file = _twitpic_filter_download_twitpic($pic_code); | |
if (!empty($pic_file)) { // found/downloaded | |
$pic_url = url($pic_file, array('absolute'=>true)); | |
// substitute plain URL w/ image | |
// @TODO pass this thru a theme hook, handle w/ imagecache if requested (by $format) | |
// temporary... | |
$replace_with = "<img src='{$pic_url}' width='300' />"; | |
//$text .= watson_debug($match, '',false); | |
// just do a simple str_replace... case-sensitive should be fine | |
// (maybe even necessary - if twitpic codes are case-sensitive) | |
// - no $count limit here, will replace all, is that ok? | |
$text = str_replace($replace, $replace_with, $text); | |
// @TODO it's coming out as a link, maybe b/c turned into links by prior filters? need to resolve | |
// @TODO remove all the watson calls, message debugging | |
} | |
} | |
} | |
return $text; // breaks loop | |
} // for | |
return $text; // unchanged | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment