A friend of mine wanted to start his own blog, and as a major astronomy buff, he picked out the Red Planet theme. I thought a nice touch would be to add the Astronomy Picture of the Day widget to his sidebar.
However, nothing is ever as easy as it seems. The plugin failed, because url file access was disabled in the php.ini configuration on the webhost. I attempted to change this using the ini_set() function, but was unsuccessful.
Not willing to give up, I rewrote a large portion of the widget that retrieves the APOD content to use cURL instead. In a nutshell, the widget uses cURL to read the APOD page for the current day. There are two images in the page - a small version and a large version. The source of both images is parsed from the captured html, and cURL is used again to fetch the image data for the small image.
Because of the security settings, I couldn't do a getimagesize() call against the image URL directly, so I had to write the image data to a temp file first, and then I was able to get the dimensions of the image to resize it to fit within the sidebar.
Here is the plugin, also available here:
<?php
/*
Plugin Name: APOD Widget
Description: Adds a sidebar widget to display the Astronomy Picture of the Day (APOD)
Author: Paul Lamb
Version: 1.3
Author URI: <a href="http://www.digitalmeandering.com/<br />
Notes:" title="http://www.digitalmeandering.com/<br />
Notes:">http://www.digitalmeandering.com/<br />
Notes:</a> The framework for this widget was politely borrowed, with no intent to give back, from the Google Search widget
Version 1.3 - Modified by Erich Beyrent [http://www.beyrent.net]
uses a CURL method for retrieving the APOD images, when URL file access is disabled
*/
function widget_apodwidget_init() {
// Check for the required plugin functions. This will prevent fatal
// errors occurring when you deactivate the dynamic-sidebar plugin.
if ( !function_exists('register_sidebar_widget') )
return;
function widget_apodwidget_returnimageandlink()
{
$apodAvailable = true;
// Grab our date-time stamps
$TodayDt = date(ymd);
$MonthDay = date(ym);
// Set the image width to 150 pixels
$ImageWidthConst = 150;
// Set the base URL for the APOD site, thanks NASA!
$URL = 'http://antwrp.gsfc.nasa.gov/apod/';
// Create our HTML file name, following this format:
// 'ap060925.html' where today's date is 09/25/2006
$Filename = 'ap'.$TodayDt.'.html';
// Append the file to the URL to create the full URL to today's APOD
$FullURL = $URL.$Filename;
// Create the regular expressions for both the regular and large image, even though at the moment I'm not even using the large image
$RegExStringSmall = 'src="image/'.$MonthDay.'/(.*)" mce_src="image/'.$MonthDay.'/(.*)" ';
$RegExStringBig = 'href="image/'.$MonthDay.'/(.*)" mce_href="image/'.$MonthDay.'/(.*)" ';
// Regular expression to validate that we have a good image to present
$RegExImageExtension= '.*(\.[Jj][Pp][Gg]|\.[Gg][Ii][Ff]|\.[Jj][Pp][Ee][Gg]|\.[Pp][Nn][Gg])';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $FullURL);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$html = curl_exec ($ch);
curl_close ($ch);
if($html == '')
{
$apodAvailable = false;
}
if (eregi ($RegExStringBig, $html, $big))
{
$ImageSrcBig = $big[1];
}
// Check for the regular image
if (eregi ($RegExStringSmall, $html, $small))
{
$ImageSrcSmall = $small[1];
}
// If the APOD is available, use CURL to fetch the image and write it to a temp file
if ($apodAvailable)
{
// Create the full image URL based on what the regular expression found
$ImageUrlSmall = $URL.'image/'.$MonthDay.'/'.$ImageSrcSmall;
$ImageUrlSmall = preg_replace("/\">/", '',$ImageUrlSmall);
// Create the full big image URL based on what the regular expression found
$ImageUrlBig = $URL.'image/'.$MonthDay.'/'.$ImageSrcBig;
$ImageUrlBig = preg_replace("/\">/", '',$ImageUrlBig);
preg_match("/.*\.jpg/", $ImageUrlSmall, $matches);
$ImageUrlSmall = $matches[0];
preg_match("/.*\.jpg/", $ImageUrlBig, $matches);
$ImageUrlBig = $matches[0];
// Check to make sure the image is a compatible format
if(eregi($RegExImageExtension, $ImageUrlSmall))
{
$ImageDimensionsBig = array();
// Fetch the image
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ImageUrlSmall);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$image = curl_exec ($ch);
curl_close ($ch);
// We need to get around the security restrictions, so we create a temp file to write the image to
$filename = "temp_".mt_rand().sha1(time());
$handle = <a href="http://twitter.com/fopen">@fopen</a>('/tmp/'.$filename,"w+");
if ($handle)
{
flock($handle,LOCK_EX);
if (fwrite($handle,$image))
{
fclose($handle);
// Get the dimensions of the image for resizing
$ImageDimensionsBig = getimagesize('/tmp/'.$filename);
//Delete the file
unlink('/tmp/'.$filename);
}
}
// We want a proportional image, so create our resize percentage based on the width
$ImageResizePercentage = ($ImageDimensionsBig[0] / $ImageWidthConst);
// Set the image width to our constant
$ImageWidthSmall = ($ImageWidthConst);
// Set the image height using the resize percentage, again porpotions are the key
$ImageHeightSmall = <a href="http://twitter.com/">@</a>($ImageDimensionsBig[1] / $ImageResizePercentage);
// Create the hyperlink to the APOD site, wrapped around the image itself, setting the target to a new window and passing in the image height and width
$ImageAndLink = '<a href="'.$FullURL.'" target="_blank"><img src="'.$ImageUrlSmall.'" width="'.$ImageWidthSmall.'" height="'.$ImageHeightSmall.'"/></a>';
return $ImageAndLink;
}
else {
$apodAvailable = false;
}
}
// The APOD wasn't available, return a message indicating as such
if (!$apodAvailable) {
return 'APOD not available
';
}
}
function widget_apodwidget($args) {
extract($args);
// Each widget can store its own options. We keep strings here.
$options = get_option('widget_apodwidget');
$title = $options['title'];
echo $before_widget;
echo $before_title . $title . $after_title;
$ApodImageAndLink = widget_apodwidget_returnimageandlink();
echo '
<div style="margin-top: 5px; text-align: left">'.$ApodImageAndLink.'</div>
';
echo $after_widget;
}
// This function creates the widget control, using the built in widget abilities for controling widgets (they only get the change the title, it's no big deal)
function widget_apodwidget_control() {
// Get our options and see if we're handling a form submission.
$options = get_option('widget_apodwidget');
if ( !is_array($options) )
$options = array('title'=>__('APOD', 'widgets'));
if ( $_POST['apodwidget-submit'] ) {
// Remember to sanitize and format use input appropriately.
$options['title'] = strip_tags(stripslashes($_POST['apodwidget-title']));
update_option('widget_apodwidget', $options);
}
// Be sure you format your options to be valid HTML attributes.
$title = htmlspecialchars($options['title'], ENT_QUOTES);
// Here is our little form segment. Notice that we don't need a
// complete form. This will be embedded into the existing form.
echo '
<p style="text-align: right"><label for="apodwidget-title">' . __('Title:') . ' <input type="text" value="'.$title.'" name="apodwidget-title" id="apodwidget-title" style="width: 200px" /></label></p>
';
echo '<input type="hidden" value="1" name="apodwidget-submit" id="apodwidget-submit" />';
}
// This registers our optional widget control form. Because of this
// our widget will have a button that reveals a 200x100 pixel form.
register_widget_control(array('APOD', 'widgets'), 'widget_apodwidget_control', 200, 100);
// This registers our widget so it appears with the other available
// widgets and can be dragged and dropped into any active sidebars.
register_sidebar_widget(array('APOD', 'widgets'), 'widget_apodwidget');
}
// Run our code later in case this loads prior to any required plugins.
add_action('widgets_init', 'widget_apodwidget_init');
?>
[tags][/tags]
Recent comments
3 weeks 5 days ago
8 weeks 1 day ago
8 weeks 1 day ago
2 years 6 days ago
2 years 1 week ago
2 years 22 weeks ago
2 years 22 weeks ago
2 years 29 weeks ago
2 years 39 weeks ago
2 years 11 weeks ago