diff --git a/README.txt b/README.txt old mode 100644 new mode 100755 diff --git a/multiping.info b/multiping.info old mode 100644 new mode 100755 index 1b5391f..452383e --- a/multiping.info +++ b/multiping.info @@ -1,6 +1,7 @@ name = Multiping description = A ping module for pinging multiple sites -core = 6.x -; version = VERSION -version = 6.x-dev +core = 7.x +version = 7.x-dev +files[] = multiping.module +files[] = pages/multiping.admin.inc \ No newline at end of file diff --git a/multiping.install b/multiping.install old mode 100644 new mode 100755 index db12732..ab525f4 --- a/multiping.install +++ b/multiping.install @@ -1,64 +1,84 @@ array( - 'id' => array('type'=>'serial', 'unsigned'=>TRUE, 'not null'=>TRUE), - 'name' => array('type'=>'varchar', 'length'=>100, 'not null'=>TRUE), - 'url' => array('type'=>'varchar', 'length'=>255, 'not null'=>TRUE), - 'method' => array('type'=>'varchar', 'length'=>50), - 'lastping' => array('type'=>'int', 'unsigned'=>TRUE, 'default'=>0), - 'whentoping' => array('type'=>'int', 'unsigned'=>TRUE, 'default'=>1), - 'submitmainrss' => array('type'=>'int', 'unsigned'=>TRUE, 'default'=>0), - 'voc' => array('type'=>'text', 'length'=>4000), - 'nodetypes' => array('type'=>'text', 'length'=>4000), - 'failcount' => array('type'=>'int', 'unsigned'=>TRUE, 'default'=>0), + return array( + 'multiping' => array( + 'fields' => array( + 'id' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'name' => array( + 'type' => 'varchar', + 'length' => 100, + 'not null' => TRUE, + ), + 'url' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + ), + 'method' => array( + 'type' => 'varchar', + 'length' => 50 + ), + 'lastping' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'default' => 0, + ), + 'whentoping' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'default' => 1, + ), + 'submitmainrss' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'default' => 0, + ), + 'voc' => array( + 'type' => 'text', + 'length' => 4000, + ), + 'nodetypes' => array( + 'type' => 'text', + 'length' => 4000, + ), + 'failcount' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'default' => 0 + ), + ), + 'primary key' => array('id'), ), - 'primary key' => array('id'), ); - return $schema; } +/** + * Implements hook_install(). + */ function multiping_install() { - drupal_install_schema('multiping'); - db_query("INSERT INTO {multiping} (id,name,url,method,lastping,whentoping,submitmainrss,voc,nodetypes,failcount) VALUES (1, 'Ping-o-matic', 'http://rpc.pingomatic.com', 'weblogUpdates.ping', 0, 9, 1, 'N;', 'N;', 0);"); -} - -function multiping_uninstall() { - drupal_uninstall_schema('multiping'); -} - -/* -function multiping_update_1() { - $result = db_query('SELECT * FROM {multiping} LIMIT 1'); - if (db_num_rows($result) == 0) { - $items[] = update_sql('DROP TABLE {multiping}'); - $items[] = _multiping_create_table1(); - } else { - $row = db_fetch_array($result); - if (!isset($row['whentoping'])) { - $items[] = _system_update_utf8(array('multiping')); - $items[] = update_sql("ALTER TABLE `multiping` ADD `whentoping` INT NOT NULL DEFAULT '1' AFTER `lastping`"); - $items[] = update_sql("ALTER TABLE `multiping` ADD `submitmainrss` INT NOT NULL DEFAULT '0' AFTER `whentoping`"); - $items[] = update_sql("ALTER TABLE `multiping` ADD `voc` text AFTER `submitmainrss`"); - $items[] = update_sql("ALTER TABLE `multiping` ADD `failcount` INT default 0 AFTER `voc`"); - } - } - return $items; -} - -function multiping_update_2() { - $items=multiping_update_1(); - $result = db_query('SELECT * FROM {multiping} LIMIT 1'); - $row = db_fetch_array($result); - if (!isset($row['nodetypes'])) { - // Add new column - $items[] = update_sql("ALTER TABLE `multiping` ADD `nodetypes` text AFTER `voc`"); - // New semantics of field whentoping - $items[] = update_sql("UPDATE `multiping` SET whentoping=3 WHERE whentoping=2"); - } - return $items; + db_insert('multiping') + ->fields(array( + 'id' => 1, + 'name' => 'Ping-o-matic', + 'url' => 'http://rpc.pingomatic.com', + 'method' => 'weblogUpdates.ping', + 'lastping' => 0, + 'whentoping' => 9, + 'submitmainrss' => 1, + 'voc' => 'N;', + 'nodetypes' => 'N;', + 'failcount' => 0, + )) + ->execute(); } -*/ - -?> diff --git a/multiping.module b/multiping.module old mode 100644 new mode 100755 index 6ecd47a..0be1f9e --- a/multiping.module +++ b/multiping.module @@ -1,167 +1,108 @@ array( - 'time_between_pings' => '10', - 'pingatonce' => false, - ), - ); - // Defaults requested? - if ($defaults) { - return $default_settings; - } - // merge settings from variable table with defaults - if ($settings == NULL) { - $settings = variable_get('multiping', array()); - foreach ($default_settings as $key => $value) { - if (is_array($value)) { - $settings[$key] = isset($settings[$key]) ? array_merge($value, $settings[$key]) : $value; - } - else if (!isset($settings[$key])) { - $settings[$key] = $value; - } - } - } - // Return result - return $settings; -} - - +define('MULTIPING_PATH', 'admin/config/services/multiping'); +define('MULTIPING_WHEN_ACTIVE', 1); +define('MULTIPING_WHEN_TAXONOMY', 2); +define('MULTIPING_WHEN_NODETYPE', 4); +define('MULTIPING_WHEN_FRONTPAGE', 8); /** * Implementation of hook_menu(). */ function multiping_menu() { - $items = array(); - $items['admin/settings/multiping'] = array( - 'title' => 'Ping services', - 'description' => 'Configure when to ping which sites', - 'page callback' => 'multiping_admin', - 'page arguments' => array(), - 'access callback' => 'user_access', - 'access arguments' => array('admin pings'), - 'type' => MENU_NORMAL_ITEM, - ); - $items['admin/settings/multiping/pingall'] = array( - 'title' => 'Ping all', - 'page callback' => 'multiping_pingall', - 'access arguments' => array('admin pings'), - 'type' => MENU_NORMAL_ITEM, - ); - $items['admin/settings/multiping/new'] = array( - 'title' => 'New ping service', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('multiping_edit_service', '0'), - 'access arguments' => array('admin pings'), - 'type' => MENU_CALLBACK, - ); - $items['admin/settings/multiping/%/edit'] = array( - 'title' => 'Edit ping service', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('multiping_edit_service', 3), - 'access arguments' => array('admin pings'), - 'type' => MENU_CALLBACK, - ); - $items['admin/settings/multiping/%/ping'] = array( - 'title' => 'Ping service', - 'page arguments' => array(3), - 'page callback' => 'multiping_ping', - 'access arguments' => array('admin pings'), - 'type' => MENU_CALLBACK, - ); - $items['admin/settings/multiping/%/delete'] = array( - 'title' => 'Delete ping service', - 'page arguments' => array(3), - 'page callback' => 'multiping_delete', - 'access arguments' => array('admin pings'), - 'type' => MENU_CALLBACK, + return array( + MULTIPING_PATH => array( + 'title' => 'Multiping Settings', + 'description' => 'Configure when to ping which sites', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('multiping_admin'), + 'access callback' => 'user_access', + 'access arguments' => array('admin pings'), + 'file' => 'pages/multiping.admin.inc', + 'type' => MENU_NORMAL_ITEM, + 'weight' => -10, + ), + MULTIPING_PATH . '/services' => array( + 'title' => 'Services', + 'description' => 'Configure when to ping which sites', + 'page callback' => 'multiping_admin_services', + 'page arguments' => array(), + 'access callback' => 'user_access', + 'access arguments' => array('admin pings'), + 'file' => 'pages/multiping.admin.inc', + 'type' => MENU_LOCAL_TASK, + ), + MULTIPING_PATH . '/pingall' => array( + 'title' => 'Ping all', + 'page callback' => 'multiping_pingall', + 'access arguments' => array('admin pings'), + 'type' => MENU_LOCAL_TASK, + ), + MULTIPING_PATH . '/new' => array( + 'title' => 'New ping service', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('multiping_edit'), + 'access arguments' => array('admin pings'), + 'type' => MENU_CALLBACK, + ), + MULTIPING_PATH . '/%/edit' => array( + 'title' => 'Edit ping service', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('multiping_edit'), + 'access arguments' => array('admin pings'), + 'type' => MENU_CALLBACK, + ), + MULTIPING_PATH . '/%/ping' => array( + 'title' => 'Ping service', + 'page arguments' => array(), + 'page callback' => 'multiping_ping', + 'access arguments' => array('admin pings'), + 'type' => MENU_CALLBACK, + ), + MULTIPING_PATH . '/%/delete' => array( + 'title' => 'Delete ping service', + 'page arguments' => array(), + 'page callback' => 'multiping_delete', + 'access arguments' => array('admin pings'), + 'type' => MENU_CALLBACK, + ), ); - return $items; } /** * Implementation of hook_perm(). */ -function multiping_perm() { - return array('admin pings'); +function multiping_permission() { + return array('admin pings' => t('Administer Multiping')); } -function _multiping_doping($pingservice) { - global $base_url; - // Assemble site name - $name=variable_get('site_name', ''); - $slogan=variable_get('site_slogan', ''); - if (strlen($slogan)>0) - $name="$name - $slogan"; - // Determine rss url - if (module_exists('taxonomy') - && ($pingservice->whentoping & _multiping_when_taxonomy) - && count($pingservice->voc)>0 && $pingservice->submitmainrss==0) { - // Taxonomy module exists, "ping only for nodes with taxonomy", - // Some taxonomy elements are actually selected, "main rss" override is off - $voc=unserialize($pingservice->voc); - $rss_url="$base_url/taxonomy/term/".implode("+", $voc)."/0/feed"; - } - else { - $rss_url="$base_url/rss.xml"; - } - // Ping! Check service method - if ($pingservice->method && strlen($pingservice->method)>0) { - //watchdog("Multiping","XML ping: ".$pingservice->url); - $result = xmlrpc($pingservice->url, $pingservice->method, $name, $base_url, $rss_url); - } - else { - $pingurl=strtr($pingservice->url, array( - "%name" => urlencode($name), - "%url" => urlencode("$base_url/"), - "%rss" => urlencode($rss_url)) - ); - $result = drupal_http_request($pingurl); - //watchdog("Multiping","Non-XML ping: ".$pingurl." Result: ".$result->code." Data: '".$result->data."'"); - if ($result->code==200) { - if (strpos($result->data, "1")==0) - $result = TRUE; else - $result = FALSE; - } - else $result = FALSE; - } - // On success: Update timestamp - if ($result) - db_query("UPDATE {multiping} SET lastping=%d WHERE id=%d", time(), $pingservice->id); - return $result; -} function _multiping_checkpings() { - $settings=_multiping_get_settings(); - $result = db_query('SELECT * FROM {multiping}'); - while ($row = db_fetch_object($result)) { + $result = db_select('multiping', 'm') + ->fields('m') + ->execute(); + foreach ($result as $row) { // Ping service active? if (! ($row->whentoping & _multiping_when_active)) { continue; } - // Default query: Published nodes only - $sql_from="{node} n"; - $sql_where="n.status>0"; + $sql_from = "SELECT * FROM {node} n "; + $sql_where = " n.status>0 "; // Taxonomy selection - if (module_exists('taxonomy') && ($row->whentoping & _multiping_when_taxonomy)) { + if (module_exists('taxonomy') && ($row->whentoping & MULTIPING_WHEN_TAXONOMY)) { // Find most recent date for nodes with given taxonomy $voc=unserialize($row->voc); - $sql_from="$sql_from, {term_node} t"; - $sql_where="$sql_where AND t.nid=n.nid AND (t.tid=" . implode(" OR t.tid=", $voc) . ")"; + $sql_from = "$sql_from, {term_node} t"; + $sql_where = "$sql_where AND t.nid=n.nid AND (t.tid=" . implode(" OR t.tid=", $voc) . ")"; } // Nodetype selection if ($row->whentoping & _multiping_when_nodetype) { $nodetype=unserialize($row->nodetypes); - $sql_where="$sql_where AND (n.type='".implode("' OR n.type='", $nodetype)."')"; + $sql_where = "$sql_where AND (n.type='" . implode("' OR n.type='", $nodetype) . "')"; } // Promoted to front page? if ($row->whentoping & _multiping_when_frontpage) { @@ -170,33 +111,33 @@ function _multiping_checkpings() { //watchdog("debug","Multiping ".$row->name.": SELECT * FROM ".$sql_from." WHERE ".$sql_where); // Get max creation and modification time $max_created = 0; - $res_time = db_query('SELECT max(created) FROM {'.$sql_from.'} WHERE '.$sql_where); + $res_time = db_query('SELECT max(created) FROM {' . $sql_from . '} WHERE ' . $sql_where); $row_time = db_fetch_array($res_time); if ($row_time) $max_created=$row_time['max(created)']; $max_changed = 0; - $res_time = db_query('SELECT max(changed) FROM {'.$sql_from.'} WHERE '.$sql_where); + $res_time = db_query('SELECT max(changed) FROM {' . $sql_from . '} WHERE ' . $sql_where); $row_time = db_fetch_array($res_time); - if ($row_time) $max_changed=$row_time['max(changed)']; - if ($max_created>$max_changed) - $lastmodified = $max_created; else - $lastmodified = $max_changed; - //watchdog("Multiping","lastmodified=".$lastmodified); - // Check wether to ping service - if ($lastmodified>$row->lastping) { + if ($row_time) $max_changed = $row_time['max(changed)']; + + ($max_created > $max_changed) ? $lastmodified = $max_created : $lastmodified = $max_changed; + + if ($lastmodified > $row->lastping) { // With every failure, exponentially increase retry time - $retry_time=$settings['global']['time_between_pings']*pow(1.5,$row->failcount); - if ($retry_time>24*60) // Retry at least once a day - $retry_time=24*60; - if ($row->lastping+60*$retry_time>time()) { - // Timeout not yet reached - watchdog("Multiping", "Timeout for service @name not yet reached", array('@name' => $row->name)); - } elseif (_multiping_doping($row)) { - watchdog("Multiping", 'Successfully notified %site.', array('%site' => $row->name)); - db_query("UPDATE {multiping} SET failcount='0' WHERE id=%d",$row->id); - } else { - watchdog("Multiping", 'Failed to notify %site.', array('%site' => $row->name), WATCHDOG_WARNING); - db_query("UPDATE {multiping} SET failcount='%d' WHERE id=%d", - ($row->failcount)+1,$row->id); + $retry_time = variable_get('multiping_time_between_pings', 10) * pow(1.5, $row->failcount); + if ($retry_time > 24*60) { // Retry at least once a day + $retry_time = 24*60; + } + if ($row->lastping+60*$retry_time > REQUEST_TIME) { + // Timeout not yet reached + watchdog("Multiping", "Timeout for service @name not yet reached", array('@name' => $row->name)); + } + elseif (_multiping_doping($row)) { + watchdog("Multiping", 'Successfully notified %site.', array('%site' => $row->name)); + db_query("UPDATE {multiping} SET failcount='0' WHERE id=%d", $row->id); + } + else { + watchdog("Multiping", 'Failed to notify %site.', array('%site' => $row->name), WATCHDOG_WARNING); + db_query("UPDATE {multiping} SET failcount='%d' WHERE id=%d", ($row->failcount)+1, $row->id); } } } @@ -208,294 +149,426 @@ function _multiping_checkpings() { * Check if sites need to be pinged. */ function multiping_cron() { - watchdog("Multiping","Cron run",array(),WATCHDOG_DEBUG); + watchdog("Multiping", "Cron run", array(), WATCHDOG_DEBUG); _multiping_checkpings(); } /** - * Implementation of hook_nodeapi(). + * Implementation of hook_node_insert(). + * If pingatonce is set, check pings. + */ +function multiping_node_insert(&$node) { + if (variable_get('multiping_pingatonce', FALSE)) { + _multiping_checkpings(); + } +} + +/** + * Implementation of hook_node_update(). * If pingatonce is set, check pings. */ -function multiping_nodeapi(&$node, $op, $a3=NULL, $a4=NULL) { - //drupal_set_message("op=".$op); - //watchdog("Multiping","op=$op"); - switch ($op) { - case 'insert': - case 'update': - $settings=_multiping_get_settings(); - if ($settings['global']['pingatonce']) - _multiping_checkpings(); - break; +function multiping_node_update(&$node) { + if (variable_get('multiping_pingatonce', FALSE)) { + _multiping_checkpings(); } } +/** + * Provide service settings form + * @return string + */ +function multiping_edit() { + return _multiping_form(); + +} -function multiping_edit_service($form_state, $id) { - $edit=array(); - $edit['id']=$id; - $edit['name']=''; - $edit['url']='http://'; - $edit['method']='weblogUpdates.ping'; - $edit['when_active']=1; - $edit['when_taxonomy']=0; - $edit['when_nodetype']=0; - $edit['when_frontpage']=0; - $edit['submitmainrss']=1; - $edit['voc']=''; - $edit['nodetype']=''; - if ($id>0) { - $result = db_query('SELECT * FROM {multiping} WHERE id=%d',$id); - $row = db_fetch_object($result); - if ($row) { - $edit['name']=$row->name; - $edit['url']=$row->url; - $edit['method']=$row->method; - $edit['when_active']=(($row->whentoping & _multiping_when_active) > 0); - $edit['when_taxonomy']=(($row->whentoping & _multiping_when_taxonomy) > 0); - $edit['when_nodetype']=(($row->whentoping & _multiping_when_nodetype) > 0); - $edit['when_frontpage']=(($row->whentoping & _multiping_when_frontpage) > 0); - $edit['submitmainrss']=$row->submitmainrss; - $edit['voc']=unserialize($row->voc); - $edit['nodetype']=unserialize($row->nodetypes); - } else { - watchdog("Multiping","Query for id=@id returned 0 rows", array('@id' => $id), WATCHDOG_WARNING); - $id=0; - } +/** + * Save service settings + * @param string $form_id + * @param array $form_state + */ +function multiping_edit_submit($form_id, &$form_state) { + $edit = $form_state['values']; + $edit['id'] = ($edit['id'] && is_numeric($edit['id'])) ? $edit['id'] : 0; + $edit['name'] = ($edit['name']) ? $edit['name'] : '(no name)'; + $edit['url'] = ($edit['url']) ? $edit['url'] : 'http://localhost/'; + $edit['method'] = ($edit['method']) ? $edit['method'] : ''; + $edit['submitmainrss'] = ($edit['submitmainrss']) ? $edit['submitmainrss'] : 0; // Not present if false! + if ($edit['submitmainrss'] > 0) { + $edit['submitmainrss'] = 1; } - $form=array(); - $form['id'] = array( - '#type' => 'hidden', - '#value' => $id, - ); - $form['name'] = array( - '#type' => 'textfield', - '#title' => t('Site name'), - '#default_value' => $edit['name'], - '#size' => 50, - '#maxlength' => 100, - '#description' => t('Displayed name of the site to be pinged'), - '#attributes' => NULL, - '#required' => TRUE, + $edit['whentoping'] = $edit['when_active'] * MULTIPING_WHEN_ACTIVE + + $edit['when_taxonomy'] * MULTIPING_WHEN_TAXONOMY + + $edit['when_nodetype'] * MULTIPING_WHEN_NODETYPE + + $edit['when_frontpage'] * MULTIPING_WHEN_FRONTPAGE; + + if ($edit['id'] == 0) { + db_insert('multiping') + ->fields( + array( + 'name' => $edit['name'], + 'url' => $edit['url'], + 'method' => $edit['method'], + 'whentoping' => $edit['whentoping'], + 'submitmainrss' => $edit['submitmainrss'], + 'voc' => serialize($edit['voc']), + 'nodetypes' => serialize($edit['nodetype']), + ) + ) + ->execute(); + } + else { + db_update('multiping') + ->fields( + array( + 'name' => $edit['name'], + 'url' => $edit['url'], + 'method' => $edit['method'], + 'whentoping' => $edit['whentoping'], + 'submitmainrss' => $edit['submitmainrss'], + 'voc' => serialize($edit['voc']), + 'nodetypes' => serialize($edit['nodetype']), + ) + ) + ->condition('id', $edit['id']) + ->execute(); + } + drupal_set_message(t('Changes saved.')); + $form_state['redirect'] = MULTIPING_PATH . '/services'; +} + +function multiping_pingall() { + $html = '

' . t('Running all pings...') . '

'; + + $header = array( + array( + 'data' => t('Name'), + 'field' => 'name', + ), + array( + 'data' => t('Status'), + ), ); - $form['url'] = array( - '#type' => 'textfield', - '#title' => t('URL'), - '#default_value' => $edit['url'], - '#size' => 50, - '#maxlength' => 255, - '#description' => t('URL of the ping service. '. - 'The following replacements will be done:
'. - '%name - Site name (and slogan)
'. - '%url - Site base URL
'. - '%rss - URL of RSS feed'), - '#attributes' => NULL, - '#required' => TRUE, + + $results = db_select('multiping', 'm') + ->fields('m') + ->extend('TableSort') + ->orderByHeader($header) + ->execute(); + + $rows = array(); + + foreach ($results as $item) { + $rows[] = array( + 'data' => array( + $item->name, + (_multiping_doping($item)) ? t('Updated') : t('Failed'), + ), + ); + } + + $html = theme('table', + array( + 'header' => $header, + 'rows' => $rows, + 'sticky' => TRUE, + ) ); - /* Todo: Submit which RSS feed? Whole feed or a feed containing only - items of the selected taxonomies? */ - $form['method'] = array( - '#type' => 'textfield', - '#title' => t('Method name'), - '#default_value' => $edit['method'], - '#size' => 50, - '#maxlength' => 50, - '#description' => t('If this is an XML service: Name of the method to be called'), - '#attributes' => NULL, - '#required' => FALSE, + + $html .= theme('pager', + array( + 'tags' => array(), + ) ); - $options = array('1' => t('Always ping'), '0' => t('Don\'t ping')); - if (module_exists('taxonomy')) { - $options['2']=t('Ping only for nodes with the following taxonomy'); + + $html .= '

' . l(t('Return'), MULTIPING_PATH) . '

'; + + return $html; +} + + +function multiping_ping() { + $id = arg(4); + watchdog("Multiping", "ping @id", array('@id' => $id)); + if (!is_numeric($id)) { + drupal_not_found(); + return; } - $form['when_active'] = array( - '#type' => 'checkbox', - '#title' => t('Service active'), - '#default_value' => $edit['when_active'], - '#description' => t('Activate or deactivate this service'), + $service = db_select('multiping', 'm') + ->fields('m') + ->condition('id', $id) + ->execute() + ->fetchObject(); + _multiping_doping($service); + drupal_set_message(t('Service updated')); + drupal_goto(MULTIPING_PATH . '/services'); +} + + +function multiping_delete() { + $id = arg(4); + watchdog("Multiping", "delete @id", array('@id' => $id)); + if (!is_numeric($id)) { + drupal_not_found(); + return; + } + db_delete('multiping') + ->condition('id', $id) + ->execute(); + drupal_set_message(t('Service deleted.')); + drupal_goto(MULTIPING_PATH . '/services'); +} + + +function _multiping_form() { + $itemid = (arg(4)!=='new') ? arg(4) : 0; + $defaults = _multiping_get_service_defaults($itemid); + $options_ping = _multiping_get_options_ping(); + + $return = array( + 'id' => array( + '#type' => 'hidden', + '#value' => $defaults['id'], + ), + 'name' => array( + '#type' => 'textfield', + '#title' => t('Site name'), + '#default_value' => $defaults['name'], + '#size' => 50, + '#maxlength' => 100, + '#description' => t('Displayed name of the site to be pinged'), + '#attributes' => NULL, + '#required' => TRUE, + ), + 'url' => array( + '#type' => 'textfield', + '#title' => t('URL'), + '#default_value' => $defaults['url'], + '#size' => 50, + '#maxlength' => 255, + '#description' => t('URL of the ping service. ' . + 'The following replacements will be done:
' . + '%name - Site name (and slogan)
' . + '%url - Site base URL
' . + '%rss - URL of RSS feed'), + '#attributes' => NULL, + '#required' => TRUE, + ), + 'method' => array( + '#type' => 'textfield', + '#title' => t('Method name'), + '#default_value' => $defaults['method'], + '#size' => 50, + '#maxlength' => 50, + '#description' => t('If this is an XML service: Name of the method to be called'), + '#attributes' => NULL, + '#required' => FALSE, + ), + 'when_active' => array( + '#type' => 'checkbox', + '#title' => t('Service active'), + '#default_value' => $defaults['when_active'], + '#description' => t('Activate or deactivate this service'), + ), ); if (module_exists('taxonomy')) { - $form['when_taxonomy'] = array( + $return['when_taxonomy'] = array( '#type' => 'checkbox', '#title' => t('Ping only for selected taxonomies'), - '#default_value' => $edit['when_taxonomy'], + '#default_value' => $defaults['when_taxonomy'], '#description' => t('Send a ping only if the node belongs to one of the follwing categories'), ); - $form['voc'] = array( + $return['voc'] = array( '#type' => 'select', '#title' => t('Taxonomy terms when to ping'), - '#default_value' => $edit['voc'], - '#options' => taxonomy_form_all(), - '#multiple' => true, + '#default_value' => $defaults['voc'], + '#options' => _multiping_get_options_taxonomy(), + '#multiple' => TRUE, '#description' => t('Ping this service if any of the taxonomy terms selected above matches the respective node'), ); - $form['submitmainrss'] = array( + $return['submitmainrss'] = array( '#type' => 'checkbox', '#title' => t('Send main RSS feed in ping'), - '#default_value' => $edit['submitmainrss'], + '#default_value' => $defaults['submitmainrss'], '#description' => t('If checked, the main RSS feed is sent; otherwise, an RSS feed containing only articles from the selected taxonomies is used.'), ); } - $form['when_nodetype'] = array( + $return['when_nodetype'] = array( '#type' => 'checkbox', '#title' => t('Ping only for selected node types'), - '#default_value' => $edit['when_nodetype'], + '#default_value' => $defaults['when_nodetype'], '#description' => t('Send a ping only if the node is one of the following node types'), ); - $form['nodetype'] = array( + $return['nodetype'] = array( '#type' => 'select', '#title' => t('Node types when to ping'), - '#default_value' => $edit['nodetype'], - '#options' => node_get_types('names'), - '#multiple' => true, + '#default_value' => $defaults['nodetypes'], + '#options' => _multiping_get_options_nodetypes(), + '#multiple' => TRUE, '#description' => t('Ping this service if any of the node types selected above matches the respective node'), ); - $form['when_frontpage'] = array( + $return['when_frontpage'] = array( '#type' => 'checkbox', '#title' => t('Ping only for nodes promoted to front page'), - '#default_value' => $edit['when_frontpage'], + '#default_value' => $defaults['when_frontpage'], '#description' => t('Send a ping only if the node is promoted to the front page'), ); - $form['submit'] = array( + $return['submit'] = array( '#type' => 'submit', '#value' => t('Submit'), ); - return $form; + return $return; } -function multiping_edit_service_submit($form_id, &$form_state) { - $edit = $form_state['values']; // TODO: Is this ok? http://drupal.org/node/144132#process-params - if ($edit['form_id']=='multiping_edit_service') { - $edit['id'] = ($edit['id'] && is_numeric($edit['id'])) ? $edit['id'] : 0; - $edit['name'] = ($edit['name']) ? $edit['name'] : '(no name)'; - $edit['url'] = ($edit['url']) ? $edit['url'] : 'http://localhost/'; - $edit['method'] = ($edit['method']) ? $edit['method'] : ''; - $edit['submitmainrss'] = ($edit['submitmainrss']) ? $edit['submitmainrss'] : 0; // Not present if false! - if ($edit['submitmainrss']>0) $edit['submitmainrss']=1; - $whentoping=$edit['when_active']*_multiping_when_active+ - $edit['when_taxonomy']*_multiping_when_taxonomy+ - $edit['when_nodetype']*_multiping_when_nodetype+ - $edit['when_frontpage']*_multiping_when_frontpage; - if ($edit['id']==0) { - db_query("INSERT INTO {multiping} (name,url,method,whentoping,submitmainrss,voc,nodetypes) ". - "VALUES ('%s','%s','%s','%s','%s','%s','%s')",$edit['name'],$edit['url'], - $edit['method'],$whentoping,$edit['submitmainrss'], - serialize($edit['voc']),serialize($edit['nodetype'])); - } else { - db_query("UPDATE {multiping} SET name='%s',url='%s',method='%s',whentoping='%s',submitmainrss='%s',voc='%s',nodetypes='%s' ". - "WHERE id=%d",$edit['name'],$edit['url'],$edit['method'],$whentoping,$edit['submitmainrss'],serialize($edit['voc']),serialize($edit['nodetype']),$edit['id']); - } +/** + * Returns defaults for given service id + * @param int $id + * @return array + */ +function _multiping_get_service_defaults($id = 0) { + if ($id == 0) { + return array( + 'id' => $id, + 'name' => '', + 'url' => 'http://', + 'method' => 'weblogUpdates.ping', + 'when_active' => 0, + 'when_taxonomy' => 0, + 'when_nodetype' => 0, + 'when_frontpage' => 0, + 'submitmainrss' => 1, + 'voc' => '', + 'nodetypes' => '', + ); } - drupal_set_message("Changes saved."); - #drupal_goto("admin/settings/multiping"); - $form_state['redirect']="admin/settings/multiping"; -} - - -function multiping_settings() { - $form=array(); - $settings=_multiping_get_settings(); - $form['global']['time_between_pings'] = array( - '#type' => 'textfield', - '#title' => t('Time between pings'), - '#default_value' => $settings['global']['time_between_pings'], - '#size' => 8, - '#maxlength' => 4, - '#description' => t('Minimum number of minutes between two pings to same site'), - '#attributes' => NULL, - '#required' => TRUE, - ); - $form['pingatonce'] = array( - '#type' => 'checkbox', - '#title' => t('Ping after post'), - '#default_value' => $settings['global']['pingatonce'], - '#description' => t('Ping directly after post/update (instead of pinging during the cron job runs)'), - ); - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Submit'), - ); - return $form; -} - + else { + $results = db_select('multiping', 'm') + ->fields('m') + ->execute() + ->fetchAssoc(); -function multiping_settings_submit($form_id, &$form_state) { - $edit = $form_state['values']; // TODO: Is this ok? http://drupal.org/node/144132#process-params - if ($edit['form_id']=='multiping_settings') { - $settings=_multiping_get_settings(); - $settings['global']['time_between_pings']=$edit['time_between_pings']; - $settings['global']['pingatonce']=$edit['pingatonce']; - variable_set('multiping', $settings); + $return = array(); + + foreach ($results as $key => $val) { + $return[$key] = $val; + } + + $return['when_active'] = ($return['whentoping'] & MULTIPING_WHEN_ACTIVE) ? 1 : 0; + $return['when_taxonomy'] = ($return['whentoping'] & MULTIPING_WHEN_TAXONOMY) ? 1 : 0; + $return['when_nodetype'] = ($return['whentoping'] & MULTIPING_WHEN_NODETYPE) ? 1 : 0; + $return['when_frontpage'] = ($return['whentoping'] & MULTIPING_WHEN_FRONTPAGE) ? 1 : 0; + + return $return; } - drupal_set_message("Changes saved."); - #drupal_goto("admin/settings/multiping"); - $form_state['redirect']="admin/settings/multiping"; } /** - * Menu callback: Admin page - */ -function multiping_admin() { - $output = ""; - // General settings - $output .= drupal_get_form('multiping_settings', $form); - // Table with services - $header = array(t('Name'), t('Last update'), array('data' => t('Operations'), 'colspan' => '3')); - $result = db_query('SELECT * FROM {multiping} ORDER BY id'); - while ($row = db_fetch_object($result)) { - if ($row->lastping==0) - $lastping=t('never'); else - $lastping=format_date($row->lastping,'small'); - $rows[] = array( - $row->name, - $lastping, - l(t('edit'),"admin/settings/multiping/".$row->id."/edit"), - l(t('ping'),"admin/settings/multiping/".$row->id."/ping"), - l(t('delete'),"admin/settings/multiping/".$row->id."/delete") - ); + * Returns options for Ping-Selection + * @return array + */ +function _multiping_get_options_ping() { + $return = array('1' => t('Always ping'), '0' => t('Don\'t ping')); + if (module_exists('taxonomy')) { + $return['2']=t('Ping only for nodes with the following taxonomy'); } - $output .= theme('table',$header,$rows); - // Links - $output .= "

".l(t('Add service'),"admin/settings/multiping/new")."

"; - return $output; + return $return; } - -function multiping_pingall() { - $output = "

".t("Running all pings...")."

"; - $header = array(t('Name'), t('Status')); - $result = db_query('SELECT * FROM {multiping} ORDER BY id'); - while ($row = db_fetch_object($result)) { - $rows[] = array($row->name,_multiping_doping($row) ? t('Ok') : t('Failed')); +/** + * Returns all nodetypes in current setup + * @return array + */ +function _multiping_get_options_nodetypes() { + $types = _node_types_build()->types; + $return = array(); + foreach ($types as $type) { + $return[$type->type] = $type->name; } - $output .= theme('table',$header,$rows); - $output .= "

".l(t('Return'),"admin/settings/multiping")."

"; - return $output; + return $return; } - -function multiping_ping($id) { - watchdog("Multiping","ping @id", array('@id' => $id)); - if (!is_numeric($id)) { - drupal_not_found(); - return; +/** + * Returns options for taxonomy-terms selector + * @return array + */ +function _multiping_get_options_taxonomy() { + $terms = array(); + if (module_exists('taxonomy')) { + $taxonomies = taxonomy_get_vocabularies(); + foreach ($taxonomies as $taxonomy) { + $termsobject = taxonomy_get_tree($taxonomy->vid); + foreach ($termsobject as $term) { + $terms[$term->tid] = $term->name; + } + } } - drupal_set_message("Not yet implemented","warning"); - drupal_goto("admin/settings/multiping"); + return $terms; } - -function multiping_delete($id) { - watchdog("Multiping","delete @id", array('@id' => $id)); - if (!is_numeric($id)) { - drupal_not_found(); - return; +/** + * Ping given service + * @global type $base_url + * @param type $pingservice + * @return boolean + */ +function _multiping_doping($pingservice) { + global $base_url; + // Assemble site name + $name = variable_get('site_name', ''); + $slogan = variable_get('site_slogan', ''); + if (strlen($slogan)>0) { + $name = $name . ' - ' . $slogan; } - db_query("DELETE FROM {multiping} WHERE id=%d",intval($id)); - drupal_set_message("Service deleted."); - drupal_goto("admin/settings/multiping"); -} - -?> + // Determine rss url + if (module_exists('taxonomy') + && ($pingservice->whentoping & MULTIPING_WHEN_TAXONOMY) + && count($pingservice->voc) > 0 && $pingservice->submitmainrss == 0) { + // Taxonomy module exists, "ping only for nodes with taxonomy", + // Some taxonomy elements are actually selected, "main rss" override is off + $voc = unserialize($pingservice->voc); + $rss_url = $base_url . '/taxonomy/term/' . implode('+', $voc) . '/0/feed'; + } + else { + $rss_url = $base_url . '/rss.xml'; + } + // Ping! Check service method + if ($pingservice->method && strlen($pingservice->method) > 0) { + //watchdog("Multiping","XML ping: ".$pingservice->url); + $result = xmlrpc($pingservice->url, array($pingservice->method => array($name, $base_url, $rss_url))); + } + else { + $pingurl=strtr($pingservice->url, array( + "%name" => urlencode($name), + "%url" => urlencode("$base_url/"), + "%rss" => urlencode($rss_url)) + ); + $result = drupal_http_request($pingurl); + //watchdog("Multiping","Non-XML ping: ".$pingurl." Result: ".$result->code." Data: '".$result->data."'" + if ($result->code==200) { + if (strpos($result->data, "1")==0) { + $result = TRUE; + } + else { + $result = FALSE; + } + } + else { + $result = FALSE; + } + } + // On success: Update timestamp + if ($result) { + db_update('multiping') + ->fields( + array( + 'lastping' => REQUEST_TIME + ) + ) + ->condition('id', $pingservice->id) + ->execute(); + } + return $result; +} \ No newline at end of file