'fieldset', '#title' => t('Published Date'), '#collapsible' => 1, '#collapsed' => 0, ); $form['date']['published_date'] = array( '#type' => 'date_select', '#default_value' => $form['#node']->published_date, '#date_format' => $format, '#date_timezone' => $local_timezone, '#date_year_range' => '0:+2', '#date_increment' => 5, ); $form['#submit'][] = 'content_distribution_node_add_form_submit'; } } // content type add form - add checkbox to enable / disable distribution of nodes of this type if (($form_id == 'node_type_form')) { $form['content_distribution'] = array( '#type' => 'fieldset', '#title' => t('Content Distribution Settings'), '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form['content_distribution']['distribute'] = array( '#type' => 'checkbox', '#title' => t('Distribute content of this type'), '#default_value' => variable_get('distribute_content_type_'.$form['#node_type']->type, 0), '#description' => t('Allows nodes of this content type to be distributed via the services module. '), ); $form['#submit'][] = 'content_distribution_node_type_form_submit'; } //hide workflow options that have no effect on CMS if ($form['#id'] == 'node-form' && $user->uid != 1) { unset($form['options']['sticky']); unset($form['options']['promote']); } } /** * Additional submit handler for the node type form. */ function content_distribution_node_type_form_submit($form, &$form_state) { // set variable to distinguish if content type is distributable or not if($form['content_distribution']['distribute']['#default_value'] !== $form_state['values']['distribute']){ if (($form_state['values']['distribute']) === 1) { variable_set('distribute_content_type_'.$form['#node_type']->type, 1); //add node ids to distribution db table. $result = db_query("SELECT nid from {node} WHERE type = '%s'", $form['#node_type']->type); while($nid = db_fetch_object($result)){ //write record in content_distribution table drupal_write_record('content_distribution', $nid); } }else{ variable_set('distribute_content_type_'.$form['#node_type']->type, 0); //delete node ids from distribution db table $result = db_query("SELECT nid from {node} WHERE type = '%s'", $form['#node_type']->type); while($nid = db_fetch_object($result)){ db_query('DELETE FROM {content_distribution} WHERE nid = %d', $nid->nid); } } } } /** * Implementation of hook_nodeapi(). * * We add the vocab_name to the taxonomy object so we can use it later * on the destination server to look up a matching vocabulary - vid is not * necessarily the same on both servers, hence using the name instead */ function content_distribution_nodeapi(&$node, $op, $teaser, $page) { $is_distributable = variable_get('distribute_content_type_'.$node->type, 0); switch ($op) { case 'load': // check if nodes of this content type are distributable if($is_distributable !== 0){ // get the published date info from the {content_distribution} table $result = db_query("SELECT published_date FROM {content_distribution} WHERE nid = %d", $node->nid); $pub_date = db_result($result); //format the date field $format = 'Y-m-d H:i'; $local_timezone = date_default_timezone_get(); $pub_date = date_make_date($pub_date,$local_timezone, DATE_UNIX); $pub_date = date_format_date($pub_date, 'custom', $format); //taxonomy objects are not available during the load op, so we need to load them ourselves $taxonomy = taxonomy_node_get_terms($node); if ($taxonomy) { $vocab_names = array(); foreach ($taxonomy as $tid => $term) { $vocab_names[$tid] = taxonomy_vocabulary_load($term->vid)->name; } } //load op must return a structured array to be appended to the $node object return array( 'vocab_names' => $vocab_names, 'published_date' => $pub_date, ); } break; case 'insert': if($is_distributable !== 0){ // convert date to timestamp before insert $published_date = $node->published_date; $published_date = date_convert($published_date, DATE_DATETIME, DATE_UNIX); db_query("INSERT INTO {content_distribution} (nid, published_date) VALUES (%d, %d)", $node->nid,$published_date); } break; case 'update': if($is_distributable !== 0){ // see if node is already in DB $result = db_query("SELECT nid FROM {content_distribution} WHERE nid = %d", $node->nid); // convert date to timestamp before insert $published_date = $node->published_date; $published_date = date_convert($published_date, DATE_DATETIME, DATE_UNIX); // if result fetched we already have a row so just update the table with new published date if (($nid = db_result($result)) != FALSE) { db_query("UPDATE {content_distribution} SET published_date = %d WHERE nid = %d", $published_date, $nid); } } break; case 'delete': // remove row from node delete if($is_distributable !== 0){ db_query('DELETE FROM {content_distribution} WHERE nid = %d', $node->nid); $sites = variable_get('distributed_sites', ''); if($sites){ //foreach site go and check if the node is there //and delete it off that site. foreach($sites as $k => $site){ $endpoint = $site['sitetext'] . '/services/xmlrpc'; $api_key = ''; //grab a session id from the system.connect method $connect = xmlrpc($endpoint, 'system.connect'); $session_id = $connect['sessid']; //call the service to delete the node on the remote site $result = xmlrpc($endpoint, 'node.deleteDistributedNode', $session_id, (int)$node->nid); if($result){ drupal_set_message(t('Deleted node on ' . $site['sitetext']. ' with node id ' . $result)); }else{ drupal_set_message(t('No node to delete on ' . $site['sitetext'])); } } } } break; } } /** * Implementation of hook_views_api(). */ function content_distribution_views_api() { return array( 'api' => 2, 'path' => drupal_get_path('module', 'content_distribution') . '/includes', ); } /** * Implementation of hook_menu(). */ function content_distribution_menu(){ $items = array(); $items['admin/settings/distribution'] = array( 'title' => t('Content Distribution Settings'), 'page callback' => 'drupal_get_form', 'page arguments' => array('content_distribution_admin_form'), 'access arguments' => array('administer content distribution'), 'description' => t('Settings for content distribution.'), 'weight' => -10, 'type' => MENU_NORMAL_ITEM ); $items ['distribution/js'] = array( 'title' => 'Javascript Site Form', 'page callback' => 'distribution_site_js', 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); return $items; } /** * Implementation of hook_perm(). * Here we add the permissions for access to our admin page. */ function content_distribution_perm() { return array('administer content distribution'); } /** * build the admin form. */ function content_distribution_admin_form(&$form_state){ $form['site_count'] = array( '#type' => 'value', '#default_value' => 1, '#value' => $form_state['values']['site_count'], ); // Add a wrapper for the choices and more button. $form['site_wrapper'] = array( '#tree' => FALSE, '#weight' => -4, '#prefix' => '
' . t('Please enter the URL(s) of the remote sites you will be distributing content to in the text fields below.'), '#suffix' => '
', ); // Container for just the poll choices. $form['site_wrapper']['site'] = array( '#tree' => TRUE, '#prefix' => '
', '#suffix' => '
', '#theme' => 'site_choices', ); $sites = variable_get('distributed_sites', ''); // set up choice count if(isset($form_state['values']['site_count'])){ $choice_count = $form_state['values']['site_count']; }else if($sites){ $choice_count = count($sites); foreach($sites as $k => $site){ $form_state['values']['site'][$k]['sitetext']['#value'] = $site['sitetext']; } }else{ $choice_count = 1; } // Add the current choices to the form. for ($delta = 0; $delta < $choice_count; $delta++) { $text = isset($form_state['values']['site'][$delta]) ? $form_state['values']['site'][$delta]['sitetext']['#value'] : ''; $form['site_wrapper']['site'][$delta] = _site_choice_form($delta, $text); } // ahah element to handle adding more sites $form['site_wrapper']['site_more'] = array( '#type' => 'submit', '#value' => t('Add More Sites'), '#description' => t("If the amount of boxes above isn't enough, click here to add more sites."), '#weight' => 1, '#submit' => array('more_sites_submit'), // If no javascript action. '#ahah' => array( 'path' => 'distribution/js', 'wrapper' => 'site-choices', 'method' => 'replace', 'effect' => 'fade', ), ); $form['site_wrapper']['submit'] = array( '#type' => 'submit', '#weight' => 2, '#value' => t('Save Settings'), ); return $form; } /** * validate function for the distribution settings form. */ function content_distribution_admin_form_validate($form, &$form_state){ // validate that the user entered a valid url // in the format http://www.site.com if($form_state['values']['site']){ foreach($form_state['values']['site'] as $k => $site){ if(empty($site['sitetext'])){continue;} else if(!(valid_url($site['sitetext'], true))){ form_set_error('sitetext', 'Site ' . ($k+1) . ' is not a valid URL, please re-enter.'); } } } } /** * submit function for the distribution settings form. */ function content_distribution_admin_form_submit($form, &$form_state){ //check there is actually a value in each text field //then save the array of fields into a variable if($form_state['values']['site']){ foreach($form_state['values']['site'] as $k => $site){ if(empty($site['sitetext'])){ unset($form_state['values']['site'][$k]); } } variable_set('distributed_sites', array_values($form_state['values']['site'])); drupal_set_message(t('Content Distribution Settings Saved.')); } } function more_sites_submit($form, &$form_state){ // increment the site count variable $form_state['values']['site_count']++; } function _site_choice_form($delta, $value = '') { $form = array( '#tree' => TRUE, ); // We'll manually set the #parents property of these fields so that // their values appear in the $form_state['values']['site'] array. $form['sitetext'] = array( '#type' => 'textfield', '#title' => t('Site @n', array('@n' => ($delta + 1))), '#default_value' => $value, '#description' => t('Enter URL in the format http://www.mysite.com'), '#parents' => array('site', $delta, 'sitetext'), ); return $form; } /** * Menu callback for AHAH additions. */ function distribution_site_js() { $delta = count($_POST['site']); // Build our new form element. $form_element = _site_choice_form($delta); //drupal_alter('form', $form_element, array(), 'poll_choice_js'); // Build the new form. $form_state = array('submitted' => FALSE); $form_build_id = $_POST['form_build_id']; // Add the new element to the stored form. Without adding the element to the // form, Drupal is not aware of this new elements existence and will not // process it. We retreive the cached form, add the element, and resave. if (!$form = form_get_cache($form_build_id, $form_state)) { exit(); } $form['site_wrapper']['site'][$delta] = $form_element; form_set_cache($form_build_id, $form, $form_state); $form += array( '#post' => $_POST, '#programmed' => FALSE, ); // Rebuild the form. $form = form_builder($_POST['form_id'], $form, $form_state); // Render the new output. $choice_form = $form['site_wrapper']['site']; unset($choice_form['#prefix'], $choice_form['#suffix']); // Prevent duplicate wrappers. $output = theme('status_messages') . drupal_render($choice_form); drupal_json(array('status' => TRUE, 'data' => $output)); } /** * Theme the admin site form for choices. * * @ingroup themeable */ function theme_site_choices($form) { // Change the button title to reflect the behavior when using JavaScript. //drupal_add_js('if (Drupal.jsEnabled) { $(document).ready(function() { $("#edit-poll-more").val("'. t('Add another choice') .'"); }); }', 'inline'); foreach (element_children($form) as $key) { // No need to print the field title every time. //unset($form[$key]['sitetext']['#title']); drupal_render($form[$key]['sitetext']); } $output .= drupal_render($form); return $output; } /** * Implementation of hook_theme() */ function content_distribution_theme() { return array( 'site_choices' => array( 'arguments' => array('form' => NULL), ), ); }