<?php

/**
 * @file
 * Testing functionality for Mollom module.
 */

/**
 * Implements hook_entity_info().
 */
function mollom_test_entity_info() {
  $info['mollom_test'] = array(
    'label' => 'Mollom test record',
    'base table' => 'mollom_test',
    'uri callback' => 'mollom_test_uri',
    'entity keys' => array(
      'id' => 'mid',
      'label' => 'title',
    ),
  );
  return $info;
}

/**
 * Entity URI callback.
 */
function mollom_test_uri($record) {
  return array(
    'path' => 'mollom-test/form/' . $record->mid,
  );
}

/**
 * Implements hook_menu().
 */
function mollom_test_menu() {
  $items['mollom-test/form'] = array(
    'title' => 'Mollom test form',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('mollom_test_form'),
    'access callback' => TRUE,
  );
  $items['mollom-test/form/%mollom_test/delete'] = array(
    'title' => 'Delete Mollom test item',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('mollom_test_delete_form', 2),
    'access callback' => TRUE,
  );
  $items['mollom-test/form/views/reset'] = array(
    'page callback' => 'mollom_test_views_reset',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Implements hook_forms().
 */
function mollom_forms() {
  $forms['mollom_basic_test_form'] = array(
    'callback' => 'mollom_test_form',
  );
  return $forms;
}

/**
 * Implements hook_mollom_form_list().
 */
function mollom_test_mollom_form_list() {
  $forms['mollom_test_form'] = array(
    'title' => 'Mollom test form',
    'entity' => 'mollom_test',
    'moderation callback' => 'mollom_test_mollom_form_moderation',
    'delete form' => 'mollom_test_delete_form',
  );
  // The basic test form is identical to the mollom_test_form, but only
  // registers minimal information (e.g., no entity or moderation callback) to
  // integrate with Mollom.
  $forms['mollom_basic_test_form'] = array(
    'title' => 'Mollom basic test form',
  );
  // Same as above, but supports elements for text analysis.
  $forms['mollom_basic_elements_test_form'] = array(
    'title' => 'Mollom basic elements test form',
  );
  // Same as mollom_test_form, but supports an entity delete callback.
  $forms['mollom_entity_test_form'] = array(
    'title' => 'Mollom entity test form',
    'entity' => 'mollom_test',
    'entity delete callback' => 'mollom_test_delete',
  );
  return $forms;
}

/**
 * Implements hook_mollom_form_info().
 */
function mollom_test_mollom_form_info($form_id) {
  if ($form_id == 'mollom_basic_test_form') {
    return array();
  }
  $form_info = array(
    'bypass access' => array('administer mollom'),
    'elements' => array(
      'title' => 'Title',
      'body' => 'Body',
      'exclude' => 'Some other field',
      'parent][child' => 'Nested element',
      'field' => 'Multiple value field',
    ),
    'mapping' => array(
      'post_id' => 'mid',
      'post_title' => 'title',
      'author_name' => 'name',
    ),
  );
  return $form_info;
}

/**
 * Page callback; Resets the mollom_test_form() [page] view counter.
 */
function mollom_test_views_reset() {
  variable_del('mollom_test.form.views');
  cache_clear_all();
  drupal_goto();
}

/**
 * Form builder for Mollom test form.
 */
function mollom_test_form($form, &$form_state, $mid = NULL) {
  // Due to #limit_validation_errors, submitting the form with the "Add" button
  // will only expose validated values in the submit handler, so our storage may
  // be incomplete. Therefore, the default values always have to be overloaded.
  $form_state += array('storage' => array());
  if (isset($mid) && ($record = mollom_test_load($mid))) {
    $form_state['storage'] = (array) $record;
  }
  $form_state['storage'] += array(
    'mid' => $mid,
    'title' => '',
    'body' => '',
    'exclude' => '',
    'parent' => array('child' => ''),
    'field' => array(),
    'status' => 1,
  );
  // Always add an empty field the user can submit.
  $form_state['storage']['field']['new'] = '';

  // Output a page view counter for page/form cache testing purposes.
  $count = variable_get('mollom_test.form.views', 1);
  $reset_link = l('Reset', 'mollom-test/form/views/reset', array('query' => drupal_get_destination()));
  $form['views'] = array(
    '#markup' => '<p>' . 'Views: ' . $count++ . ' ' . $reset_link . '</p>',
  );
  variable_set('mollom_test.form.views', $count);

  // Conditionally enable form caching.
  if (variable_get('mollom_test.form.cache', FALSE)) {
    $form_state['cache'] = TRUE;
  }

  $form['#tree'] = TRUE;
  $form['mid'] = array(
    '#type' => 'hidden',
    '#value' => $form_state['storage']['mid'],
  );
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => 'Title',
    '#default_value' => $form_state['storage']['title'],
    '#required' => TRUE,
  );
  $form['body'] = array(
    '#type' => 'textfield',
    '#title' => 'Body',
    '#default_value' => $form_state['storage']['body'],
  );
  $form['exclude'] = array(
    '#type' => 'textfield',
    '#title' => 'Some other field',
    '#default_value' => $form_state['storage']['exclude'],
  );
  $form['parent']['child'] = array(
    '#type' => 'textfield',
    '#title' => 'Nested element',
    '#default_value' => $form_state['storage']['parent']['child'],
  );

  $form['field'] = array(
    '#type' => 'fieldset',
    '#title' => 'Field',
  );
  $weight = 0;
  foreach ($form_state['storage']['field'] as $delta => $value) {
    $form['field'][$delta] = array(
      '#type' => 'textfield',
      '#title' => 'Field ' . $delta,
      '#default_value' => $value,
      '#weight' => $weight++,
    );
  }
  $form['field']['new']['#weight'] = 999;
  $form['field']['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Add',
    '#limit_validation_errors' => array(array('field')),
    '#submit' => array('mollom_test_form_field_submit'),
    '#weight' => 1000,
  );

  $form['status'] = array(
    '#type' => 'checkbox',
    '#title' => 'Published',
    '#default_value' => $form_state['storage']['status'],
    // For simplicity, re-use Mollom module's administration permission.
    '#access' => user_access('administer mollom'),
  );

  $form['actions'] = array('#type' => 'actions');
  $form['actions']['submit'] = array('#type' => 'submit', '#value' => 'Submit');

  return $form;
}

/**
 * Form element submit handler for mollom_test_form().
 */
function mollom_test_form_field_submit($form, &$form_state) {
  // Remove internal Form API values.
  form_state_values_clean($form_state);
  // Remove all empty values of the multiple value field.
  $form_state['values']['field'] = array_filter($form_state['values']['field']);
  // Update the storage with submitted values.
  $form_state['storage'] = $form_state['values'];
  // Store the new value and clear out the 'new' field.
  if (isset($form_state['values']['field']['new'])) {
    $form_state['storage']['field'][] = $form_state['values']['field']['new'];
  }
  unset($form_state['input']['field']['new']);

  $form_state['rebuild'] = TRUE;
}

/**
 * Form submit handler for mollom_test_form().
 */
function mollom_test_form_submit($form, &$form_state) {
  $form_state['values']['field'][] = $form_state['values']['field']['new'];
  unset($form_state['values']['field']['new']);

  // Store submission.
  form_state_values_clean($form_state);
  $record = (object) $form_state['values'];
  mollom_test_save($record);
  $form_state['values']['mid'] = $record->mid;

  // Redirect to stored entry.
  $form_state['redirect'] = 'mollom-test/form/' . $record->mid;

  drupal_set_message('Successful form submission.');
  drupal_set_message('<pre>' . var_export($record, TRUE) . '</pre>');
}

/**
 * Implements hook_form_alter().
 */
function mollom_test_form_alter(&$form, &$form_state, $form_id) {
  if (variable_get('mollom_test.disable_mollom', FALSE)) {
    $form_state['mollom']['require_analysis'] = FALSE;
    $form_state['mollom']['require_captcha'] = FALSE;
  }
}

/**
 * Mollom form moderation callback for a mollom_test record.
 */
function mollom_test_mollom_form_moderation(&$form, &$form_state) {
  $form_state['values']['status'] = 0;
}

/**
 * Loads a {mollom_test} data record by id.
 */
function mollom_test_load($mid) {
  return db_query('SELECT * FROM {mollom_test} WHERE mid = :mid', array(':mid' => $mid))->fetch();
}

/**
 * Saves a {mollom_test} data record.
 */
function mollom_test_save($record) {
  // Load the stored entity, if any.
  if (!empty($record->mid) && !isset($record->original)) {
    $record->original = entity_load_unchanged('mollom_test', $record->mid);
  }

  $update = !empty($record->mid) ? array('mid') : array();
  $status = drupal_write_record('mollom_test', $record, $update);
  if ($status === SAVED_NEW) {
    module_invoke_all('mollom_test_insert', $record);
    module_invoke_all('entity_insert', $record, 'mollom_test');
  }
  else {
    $status = SAVED_UPDATED;
    module_invoke_all('mollom_test_update', $record);
    module_invoke_all('entity_update', $record, 'mollom_test');
  }
  return $status;
}

/**
 * Deletes a {mollom_test} data record.
 *
 * @param int $mid
 *   The mid to delete.
 */
function mollom_test_delete($mid) {
  $record = mollom_test_load($mid);
  if ($record) {
    module_invoke_all('entity_delete', $record, 'mollom_test');
  }
  db_delete('mollom_test')
    ->condition('mid', $mid)
    ->execute();
}

/**
 * Form constructor for deleting a Mollom test item.
 */
function mollom_test_delete_form($form, &$form_state, $record) {
  $form['mid'] = array('#type' => 'value', '#value' => $record->mid);
  return confirm_form($form,
    t('Are you sure you want to delete the %title?', array('%title' => $record->title)),
    'mollom-test/form/' . $record->mid,
    NULL,
    t('Delete')
  );
}

/**
 * Form submission handler for mollom_test_delete_form().
 */
function mollom_test_delete_form_submit($form, &$form_state) {
  mollom_test_delete($form_state['values']['mid']);
  drupal_set_message('The record has been deleted.');
  $form_state['redirect'] = 'mollom-test/form';
}

