'fieldset', '#title' => 'diggthis ' . t('settings'), ); $form['diggthis']['diggthis_button_url'] = array( '#type' => 'textfield', '#title' => t('Digg Button URL'), '#default_value' => variable_get('diggthis_button_url',''), '#description' => t('The URL to the Digg button you want to use for stories that are not yet submitted to Digg.com, for example
http://digg.com/img/badges/32x32-digg-guy.gif
You can choose buttons here: ') . l(t('Digg buttons'), 'http://digg.com/tools/buttons'), ); $form['diggthis']['diggthis_node_types'] = array( '#type' => 'checkboxes', '#title' => t('Node Types'), '#default_value' => variable_get('diggthis_node_types', array()), '#options' => node_get_types(), ); $form['diggthis']['diggthis_button_teaser'] = array( '#type' => 'select', '#title' => t('Display button in teaser'), '#default_value' => variable_get('diggthis_button_teaser', 0), '#options' => array(0 => t('Disabled'), 1 => t('Enabled')), '#description' => t('Show digg button in teaser?'), ); $form['diggthis']['diggthis_button_fullview'] = array( '#type' => 'select', '#title' => t('Display button in full view'), '#default_value' => variable_get('diggthis_button_fullview', 0), '#options' => array(0 => t('Disabled'), 1 => t('Enabled')), '#description' => t('Show digg button in full view?'), ); return $form; } /** * Implementation of hook_form_alter() */ function diggthis_form_alter($form_id, &$form) { //Check we're altering the right form... if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id && in_array($form['type']['#value'], variable_get('diggthis_node_types', array()), TRUE)) { //Do we have a node value (ie editing or new?) if($form['nid']['#value']) { //We do - get the diggsource (if there is one) $diggsource = _diggthis_get_data($form['nid']['#value']); if(is_array($diggsource)) $diggsource = $diggsource['ID']; } else { //Default to blank $diggsource = NULL; } //Create a fieldset - collapse it if there is no URL, expand it if there is one set $form['diggthis'] = array( '#type' => 'fieldset', '#title' => t('Digg this'), '#collapsible' => TRUE, '#collapsed' => !isset($diggsource), '#tree' => TRUE, ); //Alternate URL field $form['diggthis']['alternate_url'] = array( '#type' => 'textfield', '#title' => t('Alternate URL'), '#default_value' => $diggsource, '#description' => t('If you wish this to link to a digg counter targetting to a page other than this page, please enter either the target URL, the Digg URL or the Digg ID. If left blank, the system will digg the current page.'), ); } } /** * Implementation of hook_nodeapi() */ function diggthis_nodeapi($node, $op, $arg = 0) { switch($op) { case 'insert' : case 'update' : //Whatever happens below - we need to clear the old entry... db_query("DELETE FROM {node_diggthis} WHERE nid = %d", $node->nid); //Get the alternate URL and trim spaces off (just in case) $alt_url = trim($node->diggthis['alternate_url']); //If alt url is empty then populate with the current node alias if(empty($alt_url)) { $alt_url = "node/".$node->nid; } //check if we're linking to a node on this site... if(preg_match("|^node/([0-9]+)|", $alt_url, $matches)) { //we're linking to a node on this site... lets sort out the URL. $alt_url = drupal_get_path_alias("node/".$matches[1]); $alt_url = "http://" . $_SERVER['SERVER_NAME'] . base_path() . $alt_url; } //We need to convert non-id's to ID's... So lets get the digg object $digg_data = array_shift(_request_diggthis($alt_url)); //If the data variable is set then that means we have a valid digg if($digg_data) { db_query("INSERT INTO {node_diggthis} (nid, type, lastupdate, diggsource, diggdata) VALUES(%d, 'ID', UNIX_TIMESTAMP(), '%s', '%s')", $node->nid, $digg_data['ID'], serialize($digg_data)); drupal_set_message(t('Sucessfully found and inserted a Digg item.'), 'status'); } else { //ok - no digg data returned... lets see what to do with the URL. if(substr($alt_url, 0, 16) == "http://digg.com/") { //if we're trying to link to a digg article and nothing was returned then there must have been a typo. //Report an error and do NOT insert anything drupal_set_message(t('Tried to link to a digg page which wasn\' found. Digg link defaulting to current node URL.'), 'error'); } else { //It must be a custom URL of somekind... db_query("INSERT INTO {node_diggthis} (nid, type, lasteupdate, diggsource) VALUES(%d, 'LINK', UNIX_TIMESTAMP(), '%s')", $node->nid, $alt_url); drupal_set_message(t('No digg item found - storing target URL for future digging.'), 'status'); } } break; case 'load' : //Load the alternate URL into the node return array('diggthis' => _diggthis_get_data($node->nid)); break; case 'delete' : //Delete the alternate node from the database db_query("DELETE FROM {node_diggthis} WHERE nid = %d", $node->nid); break; } } //Private function to get the alternate URL of a node function _diggthis_get_data($nid) { $result = db_query("SELECT dt.* FROM {node_diggthis} dt WHERE dt.nid = %d", $nid); if(db_num_rows($result)) { $row = db_fetch_object($result); if($row->diggdata) { return unserialize($row->diggdata); } else { return $row->diggsource; } } else { return NULL; } } /** * Implementation of hook_link() */ function diggthis_link($type, $node = NULL, $teaser = FALSE) { //Only digg nodes, not comments if($type == 'node') { //Check our node is one of the ok types if(in_array($node->type, variable_get('diggthis_node_types', array()), TRUE)) { //Is this a teaser view and, if so, can we digg from the teaser? if($teaser && variable_get('diggthis_button_teaser', 0)) { $link = theme('diggthis_button', $node); } //This isn't a teaser view - can we digg in fullview? else if(variable_get('diggthis_button_fullview', 0)) { $link = theme('diggthis_button', $node); } if($link) return array($link); } } } function diggthis_cron() { //First - lets update all the ID's //The threshold is set in the settings - otherwise default to 1 hour. #$threshold = time() - variable_get('diggthis_threshold', 3600); // Grab a list of ID's which are outside the threshold... $result = db_query("SELECT ndt.nid nid, ndt.diggsource diggsource FROM {node_diggthis} ndt WHERE ndt.type = 'ID' AND ndt.lastupdate < (UNIX_TIMESTAMP() - %d)", 3600); if(db_error() == 0) { watchdog('Digg This', t('Updating !upd', array('!upd' => db_num_rows($result)), WATCHDOG_NOTICE)); } else { watchdog('Digg This', t('Database Error !err', array('!err' => db_error()), WATCHDOG_ERROR)); } if(db_num_rows($result)) { $ids = array(); while($row = db_fetch_object($result)) { $ids[$row->nid] = $row->diggsource; } $diggs = _request_many_diggs(implode(",", $ids)); foreach($ids as $nid => $did) { if($diggs[$did]) { //We found something for this ID... db_query("UPDATE {node_diggthis} SET lastupdate=UNIX_TIMESTAMP(), diggdata='%s' WHERE nid=%d", serialize($diggs[$did]), $nid); } else { //nothing was returned for this ID... Hmmm... Report an error in watchdog, but update its last updated flag. db_query("UPDATE {node_diggthis} SET lastupdate=UNIX_TIMESTAMP() WHERE nid=%d", $nid); $link = drupal_get_path_alias("node/".$nid); watchdog( 'Digg This', t('Unabled to find a digg with ID %did.', array('%did' => $did) ), WATCHDOG_ERROR, l($link, $link) ); } } } //Ok - we've updated all ID's... Lets go for LINK's now. $result = db_query("SELECT ndt.nid nid, ndt.diggsource diggsource FROM {node_diggthis} ndt WHERE ndt.type = 'LINK' AND ndt.lastupdate < (UNIX_TIMESTAMP() - %d)", 3600); if(db_num_rows($result)) { //We've found some LINKS which need updating... lets see what we can do. while($row = db_fetch_object($result)) { //Lookup the current source... $digg_data = _request_diggthis($row->diggsource); if(is_array($digg_data)) { //If true then we have found new data for this source! //We need to update the system and convert from link to ID so next time its part of the mass update above. // Also - the result is in the form of ID => (array)DATA. We're only interested in the data array... $digg_data = array_shift($digg_data); //Update the database db_query("UPDATE {node_diggthis} SET type='ID', lastupdate=UNIX_TIMESTAMP(), diggsource=%d, diggdata='%s' WHERE nid=%d", $digg_data['ID'], serialize($digg_data), $row->nid); } else { //Nothing found - just updatethe timestamp... db_query("UPDATE {node_diggthis} SET lastupdate=UNIX_TIMESTAMP() where nid = %d", $row->nid); } } } } /** * Theme function */ function theme_diggthis_button($node) { if(is_array($node->diggthis)) { //Its an array - that means we have a digg object! $digg_button = _digg_button_render($node->diggthis['HREF']); } else { //Its not an array - therefore it must just be a target URL... if(isset($node->diggthis)) { $digg_button = _digg_button_render($node->diggthis, drupal_urlencode($node->title)); } else { //Ok - last resort.. Digg the current node URL! $digg_button = _digg_button_render(drupal_get_path_alias("node/".$node->nid), drupal_urlencode($node->title)); } } return '
'. $digg_button .'
'; } //Private function to render a button - NEEDS CLEANING UP function _digg_button_render($url, $title=NULL) { if ($title) { $link_title = t('Digg this!'); $button_url = variable_get('diggthis_button_url',''); if(empty($button_url)) { $link_contents = $link_title; } else { $link_contents = ''. $link_text .''; } //Set the link target $link_target = 'http://digg.com/submit?phase=2&url='. $url .'&title='.$title; $digg_button = l($link_contents, $link_target, array('title' => $link_title), NULL, NULL, FALSE, !empty($button_url)); } else { $digg_button = ""; } return $digg_button; } /** * diggthis request and XML parser functions */ function _request_diggthis($url) { global $digg_story_data; $digg_story_data = array(); //Check which type of Digg URL we have... if(substr($url, 0, 16) == "http://digg.com/") { //looks like a digg URL - looks the digg at that href $request_url = 'http://services.digg.com/stories?href=' . $url; } else if(preg_match("|[^0-9]|", $url)) { //looks like a target URL - looks up diggs for that URL (but limit to 1 result) $request_url = 'http://services.digg.com/stories?count=1&link=' . $url; } else { //Just numbers - must be an ID - lookup the ID $request_url = 'http://services.digg.com/stories/' . $url; } $ch = curl_init($request_url); curl_setopt($ch, CURLOPT_HEADER, 0); ob_start(); curl_exec($ch); $xml = ob_get_clean(); curl_close($ch); if (!$xml) { return FALSE; } $xml_parser = xml_parser_create(); xml_set_element_handler($xml_parser, "_startElement", "_endElement"); xml_parse($xml_parser, $xml); xml_parser_free($xml_parser); if($digg_story_data) { return $digg_story_data; } return FALSE; } function _request_many_diggs($ids = '') { if($ids) { global $digg_story_data; $digg_story_data = array(); $request_url = 'http://services.digg.com/stories/' . $ids; $ch = curl_init($request_url); curl_setopt($ch, CURLOPT_HEADER, 0); ob_start(); curl_exec($ch); $xml = ob_get_clean(); curl_close($ch); if (!$xml) { return FALSE; } $xml_parser = xml_parser_create(); xml_set_element_handler($xml_parser, "_startElement", "_endElement"); xml_parse($xml_parser, $xml); xml_parser_free($xml_parser); if($digg_story_data) { return $digg_story_data; } } return FALSE; } function _startElement($parser, $name, $attrs) { global $digg_story_data; if ($name == 'STORY') { $digg_story_data[$attrs['ID']] = $attrs; } } function _endElement($parser, $name) { }