default_display_options = array( 'title', 'image' ); $this->_cache_time = 86400; $this->data_source = "http://hubblesite.org/gallery/album/daily_image.php"; $this->has_simplexml = class_exists('SimpleXMLElement'); $this->_valid_column_names = array('title', 'date', 'image_url', 'gallery_url', 'credits'); $this->_valid_options = array( "image" => __("Daily Image", "hubblesite-daily-image-widget"), "title" => __("Image Title", "hubblesite-daily-image-widget"), "credits" => __("Credits", "hubblesite-daily-image-widget") ); add_action('init', array($this, "_init")); if (!$skip_load_data) { if (!$this->_load_data()) { add_action("admin_notices", array($this, "_connection_warning")); } } else { $this->data = false; } } /** * WordPress init hook. */ function _init() { register_sidebar_widget(__("HubbleSite Daily Image", "hubblesite-daily-image-widget"), array($this, "render")); register_widget_control(__("HubbleSite Daily Image", "hubblesite-daily-image-widget"), array($this, "render_ui")); $this->handle_post(); $this->get_display_options(); } /** * Display a warning if the connection failed. */ function _connection_warning() { echo "
"; _e("HubbleSite Daily Image Widget was unable to retrieve new data from HubbleSite.", "hubblesite-daily-image-widget"); _e("The widget will appear as empty in your site until data can be downloaded again.", "hubblesite-daily-image-widget"); echo "
"; } /** * Wrapper around a remote data call for unit testing purposes. * @return string The data from the remote source. */ function _get_from_data_source() { if (extension_loaded('curl')) { $ch = curl_init($this->data_source); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); $result = curl_exec($ch); curl_close($ch); return $result; } else { return @file_get_contents($this->data_source); } } /** * Load the remote data into the object. * This will try to pull from cache and, if necessary, retrieve and parse the XML from the * remote server. If any of this fails, returns false. * @return boolean True if data could be loaded, false otherwise. */ function _load_data() { if (($result = $this->_get_cached_data()) === false) { if (($xml_text = $this->_get_from_data_source()) !== false) { if (($result = $this->parse_xml($xml_text)) !== false) { update_option('hubblesite-daily-image-cache', array(time(), $result)); return true; } } return false; } else { return true; } } /** * Handle updating the widget options. */ function handle_post() { if (isset($_POST['hubblesite']['_wpnonce'])) { if (wp_verify_nonce($_POST['hubblesite']['_wpnonce'], 'hubble')) { $options = array(); foreach ($this->_valid_options as $option => $label) { if (isset($_POST['hubblesite'][$option])) { $options[] = $option; } } $this->display_options = $options; update_option('hubblesite-daily-image-options', implode(",", $this->display_options)); } } } /** * Get the list of display options from the WordPress options database. */ function get_display_options() { $display_options = get_option('hubblesite-daily-image-options'); $this->display_options = array(); if (!empty($display_options)) { $this->display_options = array_intersect(explode(",", $display_options), array_keys($this->_valid_options)); } if (empty($this->display_options)) { $this->display_options = $this->default_display_options; } update_option('hubblesite-daily-image-options', implode(",", $this->display_options)); return $this->display_options; } /** * Render the widget. * @param array $args The theme's widget layout arguments. */ function render($args) { if (!empty($this->data) && is_array($this->data)) { extract($args); $options = $this->get_display_options(); echo $before_widget; echo $before_title; echo "HubbleSite Daily Image"; echo $after_title; if (in_array("image", $options)) { echo ''; echo '' . $this->data['title'] . ''; echo ''; } if (in_array("title", $options)) { echo ''; echo $this->_fix_widows($this->data['title']); echo ''; } if (in_array("credits", $options)) { echo '
'; echo $this->_fix_widows($this->data['credits']); echo '
'; } echo $after_widget; } } /** * Render the widget admin UI. */ function render_ui() { echo ""; echo "

"; _e("Show on Widget (must select at least one):", "hubblesite-daily-image-widget"); echo "

"; foreach ($this->_valid_options as $option => $label) { echo ""; echo "
"; } } /** * Parse a string of XML from the HubbleSite Daily Gallery Image feed. * This will try to use SimpleXML if vailable. If not, will fall back on Expat. * @param string $xml_text The text to parse. * @return array|boolean The retrieved data, or false on failure. */ function parse_xml($xml_text) { if ($this->has_simplexml) { try { $xml = new SimpleXMLElement($xml_text); if ($xml !== false) { $data = array(); $is_valid = true; foreach ($this->_valid_column_names as $node) { if ($xml->{$node}) { $data[$node] = (string)$xml->{$node}; } else { $is_valid = false; break; } } if ($is_valid) { $this->data = $data; } else { $this->data = false; } } } catch (Exception $e) { $this->data = false; } } else { $parser = xml_parser_create(); $this->_character_data = ""; $this->_xml_data = array(); xml_set_element_handler( $parser, array($this, "_start_element_handler"), array($this, "_end_element_handler") ); xml_set_character_data_handler($parser, array($this, "_character_data_handler")); xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); $this->data = false; if (xml_parse($parser, $xml_text)) { if (count($this->_xml_data) == count($this->_valid_column_names)) { $this->data = $this->_xml_data; } } } return $this->data; } /** * Expat start element handler. */ function _start_element_handler($parser, $name, $attributes) { $this->_character_data = ""; } /** * Expat end element handler. */ function _end_element_handler($parser, $name) { $name = strtolower($name); if (in_array($name, $this->_valid_column_names)) { $this->_xml_data[$name] = $this->_character_data; } $this->_character_data = ""; } /** * Expat character data handler. */ function _character_data_handler($parser, $data) { $this->_character_data .= $data; } /** * Retrieve the cached data from WP Options. * @return array|boolean The cached data or false upon failure. */ function _get_cached_data() { if (($result = get_option('hubblesite-daily-image-cache')) !== false) { list($timestamp, $cached_data) = $result; if (($timestamp + $this->_cache_time) > time()) { $is_valid = true; foreach ($this->_valid_column_names as $field) { if (!isset($cached_data[$field])) { $is_valid = false; break; } } if ($is_valid) { $this->data = $cached_data; return $cached_data; } } } return false; } /** * Try to ensure that no words in a paragraph or link are widowed. * @param string $text The text to process. * @return string The processed text. */ function _fix_widows($text) { return preg_replace("#([^\ ]+)\ ([^\ \>]+)($|

|)#", '\1 \2\3', $text); } } function the_hubblesite_daily_image_widget() { $diw = new DailyImageWidget(); $diw->render(); } ?>