<?php

/**
 * @file
 * Allow users to override the default publishing options for nodes they can
 * edit without giving them the 'administer nodes' permission.
 */

/**
 * Implements hook_permisson().
 */
function override_node_options_permission() {
  $permissions = array();

  // Generate override node permissions for all applicable node types.
  foreach (node_permissions_get_configured_types() as $type) {
    $permissions += override_node_options_list_permissions($type);
  }

  return $permissions;
}

/**
 * Helper function to generate override node permission list for a given type.
 *
 * @param $type
 *   The machine-readable name of the node type.
 * @return
 *   An array of permission names and description.
 */
function override_node_options_list_permissions($type) {
  $name = node_type_get_name($type);
  $type = check_plain($type);

  $permissions = array(
    "override $type published option" => array(
      'title' => t('Override %type_name published option.', array('%type_name' => $name)),
    ),
    "override $type promote to front page option" => array(
      'title' => t('Override %type_name promote to front page option.', array('%type_name' => $name)),
    ),
    "override $type sticky option" => array(
      'title' => t('Override %type_name sticky option.', array('%type_name' => $name)),
    ),
    "override $type revision option" => array(
      'title' => t('Override %type_name revision option.', array('%type_name' => $name)),
    ),
    "enter $type revision log entry" => array(
      'title' => t('Enter %type_name revision log entry.', array('%type_name' => $name)),
    ),
    "override $type authored on option" => array(
      'title' => t('Override %type_name authored on option.', array('%type_name' => $name)),
    ),
    "override $type authored by option" => array(
      'title' => t('Override %type_name authored by option.', array('%type_name' => $name)),
    ),
  );

  return $permissions;
}

/**
 * Implements hook_form_alter().
 */
function override_node_options_form_alter(&$form, $form_state, $form_id) {
  if (!empty($form['#node_edit_form']) && !user_access('administer nodes')) {
    // Get a copy of the current node object.
    $node = $form['#node'];
    
    // Add access to the 'Revision information: log message' field
    $form['revision_information']['log']['#access'] = user_access('enter ' . $node->type . ' revision log entry');

    // Add access to the 'Revision information' fieldset.
    $form['revision_information']['revision']['#access'] = user_access('override ' . $node->type . ' revision option');
    $form['revision_information']['#access'] = element_get_visible_children($form['revision_information']);

    // Add access to the 'Authoring information' fieldset.
    $form['author']['name']['#access'] = user_access('override ' . $node->type . ' authored by option');
    $form['author']['date']['#access'] = user_access('override ' . $node->type . ' authored on option');
    if (key_exists('#access', $form['author'])) {
      $form['author']['#access'] |= element_get_visible_children($form['author']);
    }
    else {
      $form['author']['#access'] = element_get_visible_children($form['author']);
    }
    
    // Add access to the 'Publishing options' fieldset.
    $form['options']['status']['#access'] = user_access('override ' . $node->type . ' published option');
    $form['options']['promote']['#access'] = user_access('override ' . $node->type . ' promote to front page option');
    $form['options']['sticky']['#access'] = user_access('override ' . $node->type . ' sticky option');    
    if (key_exists('#access', $form['options'])) {
      $form['options']['#access'] |= element_get_visible_children($form['options']);
    }
    else {
      $form['options']['#access'] = element_get_visible_children($form['options']);
    }

    // @todo Remove when http://drupal.org/node/683630 is fixed.
    if ($form['author']['name']['#access']) {
      $form['#submit'][] = 'override_node_options_submit_node';
    }
  }
}

/**
 * Perform additional node form submission processing normally skipped by core.
 *
 * @todo Remove when http://drupal.org/node/683630 is fixed.
 */
function override_node_options_submit_node($form, &$form_state) {
  // Populate the "authored by" field.
  if ($account = user_load_by_name($form_state['values']['name'])) {
    $form_state['values']['uid'] = $account->uid;
  }
  else {
    $form_state['values']['uid'] = 0;
  }
}
