Feb 13

I found another great widget, which displays a random Apple Movie trailer, complete with movie poster.

Sadly, I ran into exactly the same problem that I did with the APOD widget - use of url file access functions is strictly verboten on my web host. So, here is the modded version of the widget to use cURL:

PHP:
  1. <?php
  2. /*
  3. Plugin Name: Apple Trailer Sidebar Widget
  4. Description: Adds a sidebar widget that shows the latest movie trailers from apple.com
  5. Author: Patrick Queisler
  6. Version: 1.1
  7. Author URI: http://www.sosuechtig.de
  8. Version 1.1 - Erich Beyrent [http://www.beyrent.net]: added cURL functions to fetch the data from Apple
  9. */
  10.  
  11. function widget_appletrailer_init() {
  12.  
  13.     if ( !function_exists('register_sidebar_widget') )
  14.         return;
  15.        
  16.     function widget_appletrailer($args) {
  17.        
  18.         extract($args);
  19.         $options = get_option('widget_appletrailer');
  20.         $title = $options['title'];
  21.        
  22.         echo $before_widget . $before_title . $title . $after_title;
  23.         function appledotcom_parser(){
  24.             $myfile = '';
  25.             $lines = @file("http://wdirect.apple.com/trailers/home/externalA.js");
  26.             if($lines)
  27.             {
  28.                 foreach ($lines as $line_num=> $line)
  29.                 {
  30.                     $myfile .= stripslashes($line);
  31.                 }
  32.             }
  33.             else
  34.             {
  35.                 $ch = curl_init();
  36.                 curl_setopt($ch, CURLOPT_URL, "http://wdirect.apple.com/trailers/home/externalA.js");
  37.                 curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
  38.                 $myfile = curl_exec($ch);
  39.                 curl_close ($ch);
  40.             }   
  41.            
  42.             $out = eregi_replace("href=\"/trailers/","target=\"_blank\" href=\"http://www.apple.com/trailers/",$myfile);
  43.             return $out;
  44.         }
  45.         function get_trailer(){
  46.             echo "<center><script language=\"JavaScript\" type=\"text/javascript\">";
  47.             echo appledotcom_parser();
  48.             echo "loadRandomD();
  49.             </script></center>";
  50.         }
  51.         get_trailer();
  52.         echo $after_widget;
  53.     }
  54.  
  55.  
  56.     function widget_appletrailer_control() {
  57.  
  58.         $options = get_option('widget_appletrailer');
  59.         if ( !is_array($options) )
  60.             $options = array('title'=>'');
  61.         if ( $_POST['appletrailer-submit'] ) {
  62.  
  63.             $options['title'] = strip_tags(stripslashes($_POST['appletrailer-title']));
  64.             update_option('widget_appletrailer', $options);
  65.         }
  66.  
  67.         $title = htmlspecialchars($options['title'], ENT_QUOTES);
  68.        
  69.         echo '<p style="text-align:right;"><label for="appletrailer-title">Title: <input style="width: 200px;" id="appletrailer-title" name="appletrailer-title" type="text" value="'.$title.'" /></label></p>';
  70.         echo '<input type="hidden" id="appletrailer-submit" name="appletrailer-submit" value="1" />';
  71.     }
  72.    
  73.     register_sidebar_widget('Apple Trailer', 'widget_appletrailer');
  74.     register_widget_control('Apple Trailer', 'widget_appletrailer_control', 300, 100);
  75. }
  76.  
  77. add_action('plugins_loaded', 'widget_appletrailer_init');
  78.  
  79. ?>

tags: , , , , , , , , ,

Feb 13

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:
  1. /*
  2. Plugin Name: APOD Widget
  3. Description: Adds a sidebar widget to display the Astronomy Picture of the Day (APOD)
  4. Author: Paul Lamb
  5. Version: 1.3
  6. Author URI: http://www.digitalmeandering.com/
  7. Notes:  The framework for this widget was politely borrowed, with no intent to give back, from the Google Search widget
  8. Version 1.3 - Modified by Erich Beyrent [http://www.beyrent.net]
  9. uses a CURL method for retrieving the APOD images, when URL file access is disabled
  10. */
  11. function widget_apodwidget_init() {
  12.  
  13. // Check for the required plugin functions. This will prevent fatal
  14. // errors occurring when you deactivate the dynamic-sidebar plugin.
  15. if ( !function_exists('register_sidebar_widget') )
  16. return;
  17.  
  18. function widget_apodwidget_returnimageandlink()
  19. {
  20. $apodAvailable = true;
  21. // Grab our date-time stamps
  22. $TodayDt = date(ymd);
  23. $MonthDay = date(ym);
  24. // Set the image width to 150 pixels
  25. $ImageWidthConst = 150;
  26. // Set the base URL for the APOD site, thanks NASA!
  27. $URL = 'http://antwrp.gsfc.nasa.gov/apod/';
  28. // Create our HTML file name, following this format:
  29. // 'ap060925.html' where today's date is 09/25/2006
  30. $Filename = 'ap'.$TodayDt.'.html';
  31. // Append the file to the URL to create the full URL to today's APOD
  32. $FullURL = $URL.$Filename;
  33.  
  34. // Create the regular expressions for both the regular and large image, even though at the moment I'm not even using the large image
  35. $RegExStringSmall = 'src="image/'.$MonthDay.'/(.*)" mce_src="image/'.$MonthDay.'/(.*)"      ';
  36. $RegExStringBig = 'href="image/'.$MonthDay.'/(.*)" mce_href="image/'.$MonthDay.'/(.*)"      ';
  37.  
  38. // Regular expression to validate that we have a good image to present
  39. $RegExImageExtension= '.*(\.[Jj][Pp][Gg]|\.[Gg][Ii][Ff]|\.[Jj][Pp][Ee][Gg]|\.[Pp][Nn][Gg])';
  40.  
  41. $ch = curl_init();
  42. curl_setopt($ch, CURLOPT_URL, $FullURL);
  43. curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
  44. $html = curl_exec ($ch);
  45. curl_close ($ch);
  46.  
  47. if($html == '')
  48. {
  49. $apodAvailable = false;
  50. }
  51.  
  52. if (eregi ($RegExStringBig, $html, $big))
  53. {
  54. $ImageSrcBig = $big[1];
  55. }
  56.  
  57. // Check for the regular image
  58. if (eregi ($RegExStringSmall, $html, $small))
  59. {
  60. $ImageSrcSmall = $small[1];
  61. }
  62.  
  63. // If the APOD is available, use CURL to fetch the image and write it to a temp file
  64. if ($apodAvailable)
  65. {
  66. // Create the full image URL based on what the regular expression found
  67. $ImageUrlSmall = $URL.'image/'.$MonthDay.'/'.$ImageSrcSmall;
  68. $ImageUrlSmall = preg_replace("/\">/", '',$ImageUrlSmall);
  69.  
  70. // Create the full big image URL based on what the regular expression found
  71. $ImageUrlBig = $URL.'image/'.$MonthDay.'/'.$ImageSrcBig;
  72. $ImageUrlBig = preg_replace("/\">/", '',$ImageUrlBig);
  73.  
  74. preg_match("/.*\.jpg/", $ImageUrlSmall, $matches);
  75. $ImageUrlSmall = $matches[0];
  76.  
  77. preg_match("/.*\.jpg/", $ImageUrlBig, $matches);
  78. $ImageUrlBig = $matches[0];
  79.  
  80. // Check to make sure the image is a compatible format
  81. if(eregi($RegExImageExtension, $ImageUrlSmall))
  82. {
  83. $ImageDimensionsBig = array();
  84.  
  85. // Fetch the image
  86. $ch = curl_init();
  87. curl_setopt($ch, CURLOPT_URL, $ImageUrlSmall);
  88. curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
  89. $image = curl_exec ($ch);
  90. curl_close ($ch);
  91.  
  92. // We need to get around the security restrictions, so we create a temp file to write the image to
  93. $filename = "temp_".mt_rand().sha1(time());
  94. $handle = @fopen('/tmp/'.$filename,"w+");
  95. if ($handle)
  96. {
  97. flock($handle,LOCK_EX);
  98. if (fwrite($handle,$image))
  99. {
  100. fclose($handle);
  101.  
  102. // Get the dimensions of the image for resizing
  103. $ImageDimensionsBig = getimagesize('/tmp/'.$filename);
  104.  
  105. //Delete the file
  106. unlink('/tmp/'.$filename);
  107. }
  108. }
  109.  
  110. // We want a proportional image, so create our resize percentage based on the width
  111. $ImageResizePercentage = ($ImageDimensionsBig[0] / $ImageWidthConst);
  112. // Set the image width to our constant
  113. $ImageWidthSmall = ($ImageWidthConst);
  114. // Set the image height using the resize percentage, again porpotions are the key
  115. $ImageHeightSmall = @($ImageDimensionsBig[1] / $ImageResizePercentage);
  116.  
  117. // 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
  118. $ImageAndLink = '<a href="'.$FullURL.'" target="_blank"><img src="'.$ImageUrlSmall.'" width="'.$ImageWidthSmall.'" height="'.$ImageHeightSmall.'"/></a>';
  119.  
  120. return $ImageAndLink;
  121. }
  122. else {
  123. $apodAvailable = false;
  124. }
  125. }
  126. // The APOD wasn't available, return a message indicating as such
  127. if (!$apodAvailable) {
  128. return 'APOD not available
  129. ';
  130. }
  131. }
  132.  
  133. function widget_apodwidget($args) {
  134. extract($args);
  135.  
  136. // Each widget can store its own options. We keep strings here.
  137. $options = get_option('widget_apodwidget');
  138. $title = $options['title'];
  139.  
  140. echo $before_widget;
  141. echo $before_title . $title . $after_title;
  142. $ApodImageAndLink = widget_apodwidget_returnimageandlink();
  143. <div style="margin-top: 5px; text-align: left">'.$ApodImageAndLink.'</div>
  144. ';
  145. echo $after_widget;
  146. }
  147.  
  148. // 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)
  149. function widget_apodwidget_control() {
  150.  
  151. // Get our options and see if we're handling a form submission.
  152. $options = get_option('widget_apodwidget');
  153. if ( !is_array($options) )
  154. $options = array('title'=>__('APOD', 'widgets'));
  155. if ( $_POST['apodwidget-submit'] ) {
  156.  
  157. // Remember to sanitize and format use input appropriately.
  158. $options['title'] = strip_tags(stripslashes($_POST['apodwidget-title']));
  159. update_option('widget_apodwidget', $options);
  160. }
  161.  
  162. // Be sure you format your options to be valid HTML attributes.
  163. $title = htmlspecialchars($options['title'], ENT_QUOTES);
  164.  
  165. // Here is our little form segment. Notice that we don't need a
  166. // complete form. This will be embedded into the existing form.
  167. <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>
  168. ';
  169. echo '<input type="hidden" value="1" name="apodwidget-submit" id="apodwidget-submit" />';
  170. }
  171.  
  172. // This registers our optional widget control form. Because of this
  173. // our widget will have a button that reveals a 200x100 pixel form.
  174. register_widget_control(array('APOD', 'widgets'), 'widget_apodwidget_control', 200, 100);
  175.  
  176. // This registers our widget so it appears with the other available
  177. // widgets and can be dragged and dropped into any active sidebars.
  178. register_sidebar_widget(array('APOD', 'widgets'), 'widget_apodwidget');
  179. }
  180.  
  181. // Run our code later in case this loads prior to any required plugins.
  182. add_action('widgets_init', 'widget_apodwidget_init');
  183. ?>

tags: , , , , , , , , ,