You are here

makemeeting.form.inc in Make Meeting Scheduler 7.2

File

makemeeting.form.inc
View source
<?php

/**
 * Form callback: enables users to answer a makemeeting poll
 */
function makemeeting_answers_form($form, &$form_state, $item, $instance, $answer = NULL) {
  global $user;
  $form = [];
  $form['#item'] = $item;
  $form['#theme'] = 'makemeeting_answers';

  // Ensure form validation and submission logic is included
  form_load_include($form_state, 'inc', 'makemeeting', 'makemeeting.form');

  // Force the id of the form as it might get overriden in AJAX-loaded forms
  $form['#id'] = 'makemeeting-answers-form';

  // Pass entity-related values in the form
  foreach ([
    'field_name',
    'entity_type',
    'deleted',
    'entity_id',
    'language',
    'delta',
  ] as $info) {
    $form[$info] = [
      '#type' => 'value',
      '#value' => $instance[$info],
    ];
  }

  // Pass answer being edited
  if ($answer) {
    $form['answer_edited'] = [
      '#type' => 'value',
      '#value' => $answer,
    ];
  }

  // Include current destination for ajax calls
  if (!isset($form_state['ajax_destination'])) {
    $form_state['ajax_destination'] = drupal_get_destination();
  }

  // Include the name of the current user
  $form['name'] = [
    '#type' => 'textfield',
    '#size' => 22,
  ];
  if (!user_is_logged_in()) {

    // This is an HTML5 attribute
    $form['name']['#attributes'] = [
      'placeholder' => t('Your name (required)'),
    ];
    $form['name']['#required'] = TRUE;
  }
  else {
    $form['name']['#default_value'] = format_username($user);
    $form['name']['#disabled'] = TRUE;
  }
  if (!empty($answer)) {
    if ($answer->uid > 0) {
      $account = user_load($answer->uid);
      $form['name']['#default_value'] = format_username($account);
    }
    else {
      $form['name']['#default_value'] = $answer->name;
    }
  }

  // If the form is limited, fetch already submitted answers
  $answers = [];
  if ($item['limit'] > 0) {
    $select = db_select('makemeeting_answers', 'ma')
      ->fields('ma', [
      'value',
    ]);
    foreach ([
      'field_name',
      'entity_type',
      'deleted',
      'entity_id',
      'language',
      'delta',
    ] as $info) {
      $select
        ->condition($info, $instance[$info]);
    }

    // Filter out answer being edited
    if ($answer) {
      $select
        ->condition('answer_id', $answer->answer_id, '!=');
    }
    $results = $select
      ->execute();

    // And add each answer to our results array for futher use
    foreach ($results as $result) {
      $_answer = unserialize($result->value);
      if (is_array($_answer)) {
        foreach ($_answer as $key => $value) {
          if ($value) {
            $answers[$key] = empty($answers[$key]) ? 1 : $answers[$key] + 1;
          }
        }
      }
      elseif (is_string($_answer) && $_answer) {
        $answers[$_answer] = empty($answers[$_answer]) ? 1 : $answers[$_answer] + 1;
      }
    }
  }

  // Possible answers
  $form['answers'] = [];
  foreach ($item['choices'] as $choice) {
    $chdate = _makemeeting_date_timestamp($choice['chdate']);
    $count = 0;
    foreach ($choice['chsuggestions'] as $id => $text) {

      // Add a form element only if there's a suggestion label
      // or it is the first suggestion for this date
      if ($text || !$text && !$count) {
        _makemeeting_answer_element($form, $item, $id, $chdate, $text, $answers, $answer);
      }
      $count++;
    }
  }
  $form['submit'] = [
    '#type' => 'submit',
    '#value' => t('Submit'),
  ];
  if (!empty($answer)) {

    // Modify form submit to include ajax behavior
    $form['submit']['#ajax'] = [
      'callback' => 'makemeeting_answer_js',
      'wrapper' => 'makemeeting-answers-form',
      'effect' => 'fade',
    ];
  }
  return $form;
}

/**
 * Form validate: validate answers
 */
function makemeeting_answers_form_validate($form, &$form_state) {

  // The required attribute won't work, so we display a single message
  if (!$form_state['values']['name']) {
    drupal_set_message(t('You must enter your name.'), 'error');
  }

  // Check is the user has already voted
  if (user_is_logged_in() && empty($form_state['values']['answer_edited'])) {
    global $user;
    $select = db_select('makemeeting_answers', 'ma');
    foreach ([
      'field_name',
      'entity_type',
      'deleted',
      'entity_id',
      'language',
      'delta',
    ] as $info) {
      $select
        ->condition($info, $form_state['values'][$info]);
    }
    $result = $select
      ->condition('uid', $user->uid)
      ->countQuery()
      ->execute()
      ->fetchField();
    if ($result) {
      form_error($form, t('You already voted on this poll.'));
    }
  }
}

/**
 * Form submit: store answers
 */
function makemeeting_answers_form_submit($form, $form_state) {
  global $user;
  if (!empty($form_state['values']['answer_edited'])) {
    db_update('makemeeting_answers')
      ->fields([
      'name' => $form_state['values']['name'],
      'value' => serialize($form_state['values']['answers']),
    ])
      ->condition('answer_id', $form_state['values']['answer_edited']->answer_id)
      ->execute();
  }
  else {
    $fields = [];
    foreach ([
      'field_name',
      'entity_type',
      'deleted',
      'entity_id',
      'language',
      'delta',
      'name',
    ] as $field) {
      $fields[$field] = $form_state['values'][$field];
    }
    db_insert('makemeeting_answers')
      ->fields($fields + [
      'value' => serialize($form_state['values']['answers']),
      'uid' => $user->uid,
    ])
      ->execute();
  }

  // Spoof drupal_get_destination()'s cache for ajax calls
  if (current_path() === 'system/ajax') {
    $destination =& drupal_static('drupal_get_destination');
    $destination = $form_state['ajax_destination'];
  }
  _makemeeting_clear_related_entity_cache($form_state['values']['entity_type'], $form_state['values']['entity_id']);
}

/**
 * Helper function to provide an answer form element
 *
 * @param $form
 *  Form to be modified
 * @param $item
 *  Item providing settings for the answer form
 * @param $id
 *  Suggestion id
 * @param \DateTime $originalDate
 *  Suggestion date
 * @param $text
 *  Suggestion text
 * @param array $answers
 *  Already submitted answers
 * @param null $answer
 *  Answer being edited
 */
function _makemeeting_answer_element(&$form, $item, $id, $originalDate, $text, $answers = [], $answer = NULL) {
  $key = $originalDate
    ->format('d-m-Y') . ':' . $id;

  // If the limit is reached for this option, display a markup text
  if ($item['limit'] > 0 && isset($answers[$key]) && $answers[$key] >= $item['limit']) {
    $form['answers'][$key] = [
      '#markup' => t('Unavailable'),
    ];
  }
  else {

    // Try to convert the hour to convert timezone
    $dateToParse = $originalDate
      ->format('d-m-Y') . ' ' . $text;
    $tz = new DateTimeZone($item['timezone']);
    $userTz = new DateTimeZone(drupal_get_user_timezone());
    if ($date = DateTime::createFromFormat('d-m-Y H\\h', $dateToParse, $tz)) {
      $title = $date
        ->setTimezone($userTz)
        ->format('l j F Y H\\h');
    }
    elseif ($date = DateTime::createFromFormat('d-m-Y H:i', $dateToParse, $tz)) {
      $title = $date
        ->setTimezone($userTz)
        ->format('l j F Y H:i');
    }
    elseif ($date = DateTime::createFromFormat('d-m-Y H a', $dateToParse, $tz)) {
      $title = $date
        ->setTimezone($userTz)
        ->format('l j F Y H a');
    }
    else {
      $title = $originalDate
        ->format('l j F Y') . ' ' . $text;
    }
    $form['answers'][$key] = [
      '#type' => $item['one_option'] ? 'radio' : ($item['yesnomaybe'] ? 'radios' : 'checkbox'),
      '#attributes' => [
        'title' => check_plain($title),
      ],
      '#parents' => [
        'answers',
        $key,
      ],
    ];
    if ($item['one_option']) {
      $form['answers'][$key]['#parents'] = [
        'answers',
      ];
      $form['answers'][$key]['#return_value'] = $key;
    }
    else {
      $form['answers'][$key]['#options'] = _makemeeting_options($item['yesnomaybe']);
    }
    if ($item['yesnomaybe']) {
      $form['answers'][$key]['#default_value'] = MAKEMEETING_NO;
    }

    // Display previous choice if answer is being edited
    if ($answer && !empty($answer->value[$key])) {
      $form['answers'][$key]['#default_value'] = $answer->value[$key];
    }
  }
}

Functions

Namesort descending Description
makemeeting_answers_form Form callback: enables users to answer a makemeeting poll
makemeeting_answers_form_submit Form submit: store answers
makemeeting_answers_form_validate Form validate: validate answers
_makemeeting_answer_element Helper function to provide an answer form element