Index: override_node_options.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/override_node_options/override_node_options.info,v
retrieving revision 1.4.2.2
diff -u -p -r1.4.2.2 override_node_options.info
--- override_node_options.info	30 Nov 2009 19:33:25 -0000	1.4.2.2
+++ override_node_options.info	27 Dec 2009 23:45:14 -0000
@@ -1,5 +1,4 @@
-; $Id: override_node_options.info,v 1.4.2.2 2009/11/30 19:33:25 joachim Exp $ 
-name = Override Node Publishing Options
+; $Id: override_node_options.info,v 1.4.2.2 2009/11/30 19:33:25 joachim Exp $
+name = Override node options
 description = "Allow non-admins to override the default publishing options for nodes they can edit."
 core = 6.x
-
Index: override_node_options.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/override_node_options/override_node_options.module,v
retrieving revision 1.5.2.15
diff -u -p -r1.5.2.15 override_node_options.module
--- override_node_options.module	27 Dec 2009 20:16:27 -0000	1.5.2.15
+++ override_node_options.module	27 Dec 2009 23:45:14 -0000
@@ -42,87 +42,58 @@ function override_node_options_menu() {
  * Implements hook_form_alter().
  */
 function override_node_options_form_alter(&$form, $form_state, $form_id) {
-  if (isset($form['type']['#value']) && $form['type']['#value'] . '_node_form' == $form_id && !user_access('administer nodes')) {
+  if (isset($form['type']['#value']) && $form['type']['#value'] . '_node_form' == $form_id) {
+    if (user_access('administer nodes')) {
+      // Modifications are not necessary for node admins.
+      return;
+    }
+
+    // Get a copy of the current node object.
     $node = $form['#node'];
 
-    /* make sure the preview shows the correct values */
-    if (isset($node->op) && $node->op == 'Preview') {
-      _override_node_options_apply_keys($node);
-    }
-
-    if (user_access('override ' . $form['type']['#value'] . ' published option') || user_access('override ' . $form['type']['#value'] . ' promote to front page option') || user_access('override ' . $form['type']['#value'] . ' sticky option') || user_access('override ' . $form['type']['#value'] . ' revision option')) {
-      $form['options'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Publishing options'),
-        '#collapsible' => variable_get('override_node_options_pocollapsible', 1),
-        '#collapsed' => variable_get('override_node_options_pocollapsed', 1),
-        '#weight' => 25,
-      );
-    }
-    if (user_access('override ' . $form['type']['#value'] . ' published option')) {
-      $form['options']['override_publishing_status'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Published'),
-        '#default_value' => $node->status,
-      );
-    }
-
-    if (user_access('override ' . $form['type']['#value'] . ' promote to front page option')) {
-      $form['options']['override_publishing_promote'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Promoted to front page'),
-        '#default_value' => $node->promote,
-      );
-    }
-
-    if (user_access('override ' . $form['type']['#value'] . ' sticky option')) {
-      $form['options']['override_publishing_sticky'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Sticky at top of lists'),
-        '#default_value' => $node->sticky,
-      );
-    }
-
-    if (user_access('override ' . $form['type']['#value'] . ' revision option')) {
-      $form['options']['override_publishing_revision'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Create new revision'),
-        '#default_value' => $node->revision,
-      );
-    }
-    if (user_access('override ' . $form['type']['#value'] . ' authored by option') || user_access('override ' . $form['type']['#value'] . ' authored on option')) {
-      $form['author'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Authoring information'),
-        '#collapsible' => variable_get('override_node_options_aicollapsible', 1),
-        '#collapsed' => variable_get('override_node_options_aicollapsed', 1),
-        '#weight' => 20,
-      );
-    }
-    if (user_access('override ' . $form['type']['#value'] . ' authored by option')) {
-      $form['author']['override_authored_by'] = array(
-        '#type' => 'textfield',
-        '#title' => t('Authored by'),
-        '#maxlength' => 60,
-        '#default_value' => $node->name,
-        '#weight' => -1,
-        '#description' => t('Leave blank for %anonymous.', array('%anonymous' => variable_get('anonymous', t('Anonymous')))),
-      );
-
-      // User must have permission 'access user profiles' for autocomplete
-      if (user_access('access user profiles')) {
-        $form['author']['override_authored_by']['#autocomplete_path'] = 'user/autocomplete';
-      }
-    }
-
-    if (user_access('override ' . $form['type']['#value'] . ' authored on option')) {
-      $form['author']['override_authored_on'] = array(
-        '#type' => 'textfield',
-        '#title' => t('Authored on'),
-        '#maxlength' => 25,
-        '#default_value' => $node->date,
-        '#description' => t('Format: %time. Leave blank to use the time of form submission.', array('%time' => !empty($node->date) ? $node->date : format_date($node->created, 'custom', 'Y-m-d H:i:s O'))),
-      );
+    // Core doesn't include the revision fieldset if the user does not have
+    // access to it unlike all the other fieldsets, so we have to re-create it.
+    // @see http://drupal.org/node/668806
+    $form['revision_information'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Revision information'),
+      '#collapsible' => TRUE,
+      '#collapsed' => !$node->revision,
+      '#weight' => 20,
+    );
+    $form['revision_information']['revision'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Create new revision'),
+      '#default_value' => $node->revision,
+      '#access' => user_access('administer nodes') || user_access('override ' . $node->type . ' revision option'),
+    );
+    $form['revision_information']['log'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Log message'),
+      '#default_value' => (isset($node->log) ? $node->log : ''),
+      '#rows' => 2,
+      '#description' => t('An explanation of the additions or updates being made to help other authors understand your motivations.'),
+    );
+    $form['revision_information']['#access'] = !empty($node->revision) || $form['revision_information']['revision']['#access'];
+
+    // 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');
+    $form['author']['#access'] |= override_node_options_element_children_access($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');
+    $form['options']['#access'] |= override_node_options_element_children_access($form['options']);
+
+    // Add extra validation and processing if the user does not have the
+    // 'administer nodes' permission since it would be otherwise skipped by core.
+    if ($form['author']['#access']) {
+      $form['#validate'][] = 'override_node_options_validate_node';
+    }
+    if ($form['author']['name']['#access']) {
+      $form['#submit'][] = 'override_node_options_submit_node';
     }
   }
 
@@ -130,8 +101,8 @@ function override_node_options_form_alte
     $form['options']['#collapsible'] = variable_get('override_node_options_pocollapsible', 1);
     $form['options']['#collapsed'] = variable_get('override_node_options_pocollapsed', 1);
 
-    $form['options']['#collapsible'] = variable_get('override_node_options_aicollapsible', 1);
-    $form['options']['#collapsed'] = variable_get('override_node_options_aicollapsed', 1);
+    $form['author']['#collapsible'] = variable_get('override_node_options_aicollapsible', 1);
+    $form['author']['#collapsed'] = variable_get('override_node_options_aicollapsed', 1);
 
     if (module_exists('upload')) {
       $form['attachments']['#collapsible'] = variable_get('override_node_options_facollapsible', 1);
@@ -144,62 +115,59 @@ function override_node_options_form_alte
   }
 }
 
+/**
+ * Perform additional node form validation normally skipped by core.
+ */
+function override_node_options_validate_node($form, $form_state) {
+  $node = (object) $form_state['values'];
 
-function _override_node_options_apply_keys(&$node) {
-  $keys = array(
-    'override_publishing_status' => 'status',
-    'override_publishing_promote' => 'promote',
-    'override_publishing_sticky' => 'sticky',
-    'override_publishing_revision' => 'revision',
-  );
-
-  $options = variable_get('node_options_' . $node->type, NULL);
-  if ($options) {
-    foreach ($options as $option) {
-      $default->$option = $option;
+  if ($form['author']['name']['#access']) {
+    // Validate the "authored by" field.
+    if (!empty($node->name) && !($account = user_load(array('name' => $node->name)))) {
+      // The use of empty() is mandatory in the context of usernames
+      // as the empty string denotes the anonymous user. In case we
+      // are dealing with an anonymous user we set the user ID to 0.
+      form_set_error('name', t('The username %name does not exist.', array('%name' => $node->name)));
+    }
+  }
+  if ($form['author']['date']['#access']) {
+    // Validate the "authored on" field. As of PHP 5.1.0, strtotime returns FALSE instead of -1 upon failure.
+    if (!empty($node->date) && strtotime($node->date) <= 0) {
+      form_set_error('date', t('You have to specify a valid date.'));
     }
   }
+}
 
-  foreach ($keys as $override_key => $real_key) {
-    if (isset($node->$override_key)) {
-      $node->$real_key = $node->$override_key;
-    }
-    elseif (isset($default->$real_key)) {
-      $node->$real_key = TRUE;
-    }
-  }
+/**
+ * Perform additional node form submission processing normally skipped by core.
+ */
+function override_node_options_submit_node($form, &$form_state) {
+  $node = (object) $form_state['values'];
 
-  // Node creation date override
-  if (isset($node->override_authored_on) && user_access('override ' . $node->type . ' authored on option') && ($node->date != $node->override_authored_on)) {
-    $node->date = $node->override_authored_on;
-    $node->created = !empty($node->override_authored_on) ? strtotime($node->override_authored_on) : time();
+  // Populate the "authored by" field.
+  if ($account = user_load(array('name' => $node->name))) {
+    $node->uid = $account->uid;
   }
-
-  if (isset($node->override_authored_by) && user_access('override ' . $node->type . ' authored by option') && ($node->name != $node->override_authored_by)) {
-    if (!empty($node->override_authored_by)) {
-      $account = user_load(array('name' => $node->override_authored_by));
-      $node->name = $account->name;
-      $node->uid = $account->uid;
-    }
-    else {
-      $node->name = "";
-      $node->uid = 0;
-    }
+  else {
+    $node->uid = 0;
   }
+
+  $form_state['values'] = (array) $node;
 }
 
 /**
- * Implements hook_nodeapi().
+ * Check if there is a child element accessible in a parent element.
+ *
+ * @param $element
+ *   A form element.
+ * @return
+ *   TRUE if a child element of $element if accessible, or FALSE otherwise.
  */
-function override_node_options_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
-  switch ($op) {
-    case 'presave':
-      // Allow users with 'override node publishing options' to change node
-      // options.
-      // TODO: Once in core, remove adminster nodes check.
-      if (!user_access('administer nodes')) {
-        _override_node_options_apply_keys($node);
-      }
-      break;
+function override_node_options_element_children_access($element) {
+  foreach (element_children($element) as $key) {
+    if (!isset($element[$key]['#access']) || !empty($element[$key]['#access'])) {
+      return TRUE;
+    }
   }
+  return FALSE;
 }
Index: override_node_options.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/override_node_options/Attic/override_node_options.test,v
retrieving revision 1.1.2.10
diff -u -p -r1.1.2.10 override_node_options.test
--- override_node_options.test	27 Dec 2009 20:19:41 -0000	1.1.2.10
+++ override_node_options.test	27 Dec 2009 23:45:14 -0000
@@ -6,196 +6,120 @@
  * Unit tests for the override_node_options module.
  */
 
-/**
- * Abstract class to hold common stuff.
- */
-class OverrideNodeOptionsCommonTestCase extends DrupalWebTestCase {
-  /**
-   * Define and return array that describes the tests to run.
-   *
-   * This allows us to abstract the tests which do the same sort of thing but
-   * on different node form fields.
-   *
-   * @return
-   *  An array of test set items, each of which itself is an array with the following
-   *  keys:
-   *  - perm: The permission the privileged user should have
-   *  - message_string: The text to insert into assertion messages.
-   *  - form_name_normal: The form element name on normal forms, ie what to check
-   *    the ordinary user can't see.
-   *  - form_name_override: The form element name on overridden forms, ie what
-   *    to check the privileged user can see.
-   *  - form_value: The value a test should attempt to set in the form.
-   *  - db_table, db_field, db_value: The table and field in the database that
-   *    altering this field should affect, and the value that is expected.
-   */
-  protected function testSets() {
-    $time = 1261267200;
-    return array(
-      'status' => array(
-        'perm' => 'override page published option',
-        'message_string' => 'Published checkbox',
-        'form_name_normal' => 'status',
-        'form_name_override' => 'override_publishing_status',
-        'form_value' => FALSE,
-        'db_table' => 'node',
-        'db_field' => 'status',
-        'db_value' => FALSE,
-      ),
-      'author' => array(
-        'perm' => 'override page authored by option',
-        'message_string' => 'Author field',
-        'form_name_normal' => 'name',
-        'form_name_override' => 'override_authored_by',
-        'form_value' => ' ', // Empty string does not work with drupalPost for some reason: @see http://drupal.org/node/649618.
-        'db_table' => 'node',
-        'db_field' => 'uid',
-        'db_value' => 0,
-      ),
-      'date' => array(
-        'perm' => 'override page authored on option',
-        'message_string' => 'Authored on date field',
-        'form_name_normal' => 'date',
-        'form_name_override' => 'override_authored_on',
-        'form_value' => date('Y-m-d', $time), // '2009-12-20'
-        'db_table' => 'node',
-        'db_field' => 'created',
-        'db_value' => $time,
-      ),
-      'promote' => array(
-        'perm' => 'override page promote to front page option',
-        'message_string' => 'Promoted checkbox',
-        'form_name_normal' => 'promote',
-        'form_name_override' => 'override_publishing_promote',
-        'form_value' => TRUE, // we create a page, they are not promoted by default
-        'db_table' => 'node',
-        'db_field' => 'promote',
-        'db_value' => 1,
-      ),
-      'sticky' => array(
-        'perm' => 'override page sticky option',
-        'message_string' => 'Sticky checkbox',
-        'form_name_normal' => 'sticky',
-        'form_name_override' => 'override_publishing_sticky',
-        'form_value' => TRUE,
-        'db_table' => 'node',
-        'db_field' => 'sticky',
-        'db_value' => 1,
-      ),
-      'revision' => array(
-        'perm' => 'override page revision option',
-        'message_string' => 'Published checkbox',
-        'form_name_normal' => 'revision',
-        'form_name_override' => 'override_publishing_revision',
-        'form_value' => TRUE,
-        'db_table' => 'node_revisions',
-        // Since we act on a fresh node, it suffices to check there is now more than one revision
-        'db_field' => 'COUNT(vid)',
-        'db_value' => 2,
-      ),
-    );
-  }
-}
-
-/**
- * Test that fields are visible only to the users they ought to be visible to.
- */
-class OverrideNodeOptionsFormsTestCase extends OverrideNodeOptionsCommonTestCase {
+class OverrideNodeOptionsTestCase extends DrupalWebTestCase {
+  protected $normal_user;
+  protected $admin_user;
+  protected $node;
 
   public static function getInfo() {
     return array(
-      'name' => 'Override Node Options forms',
-      'description' => 'Check that override permissions show the right form elements.',
-      'group' => 'Override Node Options Tests',
+      'name' => 'Override node options',
+      'description' => 'Functional tests for overridding options on node forms.',
+      'group' => 'Override node options',
     );
   }
 
   public function setUp() {
-    parent::setUp('override_node_options');  // Enable any modules required for the test
+    parent::setUp('override_node_options');
+    $this->normal_user = $this->drupalCreateUser(array('create page content', 'edit any page content'));
+    $this->node = $this->drupalCreateNode();
   }
 
-  public function testOverrideNodeOptionsFieldVisibility() {
-    // Create our regular user
-    $ordinary_user = $this->drupalCreateUser(array('create page content', 'edit any page content'));
-    $this->drupalLogin($ordinary_user);
-    // We create and later edit a node rather than just look at /node/add/page because new nodes
-    // don't show the revisions checkbox.
-    $node = $this->drupalCreateNode();
-    $nid = $node->nid;
-
-    // We iterate over the test sets.
-    // For each set, we need to check an overridden user sees the form item,
-    // and a regular user does not.
-    $test_set_list = $this->testSets();
-    foreach ($test_set_list as $key => $test_set) {
-      // Create and test the override user.
-      $override_user = $this->drupalCreateUser(array('create page content', 'edit any page content', $test_set['perm']));
-      $this->drupalLogin($override_user);
-      $this->drupalGet("node/$nid/edit");
-
-      $this->assertFieldByName($test_set['form_name_override'], '', t($test_set['message_string'] . ' is displayed to override user'));
-
-      // Test that the current override user can't see any of the other fields
-      // (eg, that if you have the override to publish you can't sticky.
-      // Get the list of test sets and remove the item for the current test.
-      $other_field_list = $test_set_list;
-      unset($other_field_list[$key]);
-      // Iterate over the other fields.
-      foreach ($other_field_list as $other_field) {
-        $this->assertNoField($other_field['form_name_override'], '', t($other_field['message_string'] . ' is not displayed to override user with ' . $test_set['message_string']));
-      }
-
-      // Test the regular user.
-      $this->drupalLogin($ordinary_user);
-      $this->drupalGet("node/$nid/edit");
-
-      $this->assertNoField($test_set['form_name_override'], '', t($test_set['message_string'] . ' is not displayed to normal user'));
+  /**
+   * Assert that fields in a node were updated to certail values.
+   *
+   * @param $node
+   *   The node object to check (will be reloaded from the database).
+   * @param $fields
+   *   An array of values to check equality, keyed by node object property.
+   */
+  function assertNodeFieldsUpdated(stdClass $node, array $fields) {
+    // Re-load the node from the database to make sure we have the current
+    // values.
+    $node = node_load($node->nid, NULL, TRUE);
+    foreach ($fields as $field => $value) {
+      $this->assertEqual($node->$field, $value, t('Node @field was updated to !value, expected !expected.', array('@field' => $field, '!value' => var_export($node->$field, TRUE), '!expected' => var_export($value, TRUE))));
     }
   }
-}
 
-/**
- * Test the user's input in override fields has the correct effect on the database.
- */
-class OverrideNodeOptionsDatabaseTestCase extends OverrideNodeOptionsCommonTestCase {
+  /**
+   * Assert that the user cannot access fields on node add and edit forms.
+   *
+   * @param $node
+   *   The node object, will be used on the node edit form.
+   * @param $fields
+   *   An array of form fields to check.
+   */
+  function assertNodeFieldsNoAccess(stdClass $node, array $fields) {
+    $this->drupalGet('node/add/' . $node->type);
+    foreach ($fields as $field) {
+      $this->assertNoFieldByName($field);
+    }
 
-  public static function getInfo() {
-    return array(
-      'name' => 'Override Node Options database testing',
-      'description' => 'Check that the changes the user makes to the node form act on the database.',
-      'group' => 'Override Node Options Tests',
-    );
+    $this->drupalGet('node/' . $this->node->nid . '/edit');
+    foreach ($fields as $field) {
+      $this->assertNoFieldByName($field);
+    }
   }
 
-  public function setUp() {
-    parent::setUp('override_node_options');  // Enable any modules required for the test
+  /**
+   * Test the 'Authoring information' fieldset.
+   */
+  function testNodeOptions() {
+    $this->admin_user = $this->drupalCreateUser(array('create page content', 'edit any page content', 'override page published option', 'override page promote to front page option', 'override page sticky option'));
+    $this->drupalLogin($this->admin_user);
+
+    $fields = array(
+      'status' => (bool) !$this->node->status,
+      'promote' => (bool) !$this->node->promote,
+      'sticky' => (bool) !$this->node->sticky,
+    );
+    $this->drupalPost('node/' . $this->node->nid . '/edit', $fields, t('Save'));
+    $this->assertNodeFieldsUpdated($this->node, $fields);
+
+    $this->drupalLogin($this->normal_user);
+    $this->assertNodeFieldsNoAccess($this->node, array_keys($fields));
   }
 
-  public function testOverrideNodeOptionsDatabase() {
-    $test_set_list = $this->testSets();
+  /**
+   * Test the 'Revision information' fieldset.
+   */
+  function testNodeRevisions() {
+    $this->admin_user = $this->drupalCreateUser(array('create page content', 'edit any page content', 'override page revision option'));
+    $this->drupalLogin($this->admin_user);
 
-    $perms = array('create page content', 'edit any page content');
-    foreach ($test_set_list as $key => $test_set) {
-      $perms[] = $test_set['perm'];
-    }
-    $user = $this->drupalCreateUser($perms);
-    $this->drupalLogin($user);
-    $other_user = $this->drupalCreateUser();
-
-    $node = $this->drupalCreateNode();
-    $nid = $node->nid;
-
-    // Iterate over the test sets.
-    foreach ($test_set_list as $key => $test_set) {
-      // Edit the node.
-      $edit = array(
-        'title' => $this->randomString(),
-        $test_set['form_name_override'] => $test_set['form_value'],
-      );
-      $this->drupalPost("node/$nid/edit", $edit, 'Save');
+    $fields = array(
+      'revision' => TRUE,
+    );
+    $this->drupalPost('node/' . $this->node->nid . '/edit', $fields, t('Save'));
+    $this->assertNodeFieldsUpdated($this->node, array('vid' => $this->node->vid + 1));
 
-      // Check the database.
-      $this->assertTrue(db_result(db_query('SELECT %s FROM {%s} WHERE nid = %d', $test_set['db_field'], $test_set['db_table'], $node->nid)) == $test_set['db_value'], t("Node successfully changed: $key is now " . $test_set['db_value']));
-    }
+    $this->drupalLogin($this->normal_user);
+    $this->assertNodeFieldsNoAccess($this->node, array_keys($fields));
+  }
+
+  /**
+   * Test the 'Authoring information' fieldset.
+   */
+  function testNodeAuthor() {
+    $this->admin_user = $this->drupalCreateUser(array('create page content', 'edit any page content', 'override page authored on option', 'override page authored by option'));
+    $this->drupalLogin($this->admin_user);
+
+    $this->drupalPost('node/' . $this->node->nid . '/edit', array('name' => 'invalid-user'), t('Save'));
+    $this->assertText('The username invalid-user does not exist.');
+
+    $this->drupalPost('node/' . $this->node->nid . '/edit', array('date' => 'invalid-date'), t('Save'));
+    $this->assertText('You have to specify a valid date.');
+
+    $time = time() + 500;
+    $fields = array(
+      'name' => '',
+      'date' => format_date($time, 'custom', 'Y-m-d H:i:s O'),
+    );
+    $this->drupalPost('node/' . $this->node->nid . '/edit', $fields, t('Save'));
+    $this->assertNodeFieldsUpdated($this->node, array('uid' => 0, 'created' => $time));
+
+    $this->drupalLogin($this->normal_user);
+    $this->assertNodeFieldsNoAccess($this->node, array_keys($fields));
   }
 }
