Score:1

Webform handler to manage number of places available

cn flag

I want to manage a webform to automatically close it if number of people reached, or to invalid submission if not enough places are available.

I have use this : Close a webform when total seats reach a maximum to try to make a handler

here is my code :

<?php
namespace Drupal\webform_reservations\Plugin\WebformHandler;

use Drupal\Core\Form\FormStateInterface;
use Drupal\webform\Plugin\WebformHandlerBase;
use Drupal\webform\webformSubmissionInterface;

/**
 * Form submission handler.
 *
 * @WebformHandler(
 * id = "webform_reservations_handler",
 * label = @Translation("Reservations Handler"),
 * category = @Translation("Form Handler"),
 * description = @Translation("Manage maximum reservations by submission. Be Carfull some parameters are needed for working !"),
 * cardinality = \Drupal\webform\Plugin\WebformHandlerInterface::CARDINALITY_SINGLE,
 * results = \Drupal\webform\Plugin\WebformHandlerInterface::RESULTS_PROCESSED,
 * )
 */

class ReservationHandler extends WebformHandlerBase {

  /**
   * {@inheritdoc}
   */

  public function submitForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission) {
    $webform = $webform_submission->getWebform();
    $formid = $webform->id();
    $event_max_people= $webform_submission->getElementData('event_max_people');

//query the db for all submissions of current webform submission
    $query = \Drupal::entityQuery('webform_submission');
    $query->condition('webform_id', $formid);
    $result = $query->execute();

//load all the submissions from the results
    $storage = \Drupal::entityTypeManager()->getStorage('webform_submission');
    $submissions = $storage->loadMultiple($result);
    $submission_data = array();

    foreach ($submissions as $submission) {
      $submission_data[] = $submission->getData();
    }
    $current_reserved = 0;
//add up all the values in the 'number_of_people' field of each submission and save it to a variable.
    for ($i = 0; $i < count($submission_data); $i++){
      $current_reserved += $submission_data[$i]['number_of_people'];
    }

    if ($event_max_people <= $current_reserved) {
      // normally impossible state because the form automatically close when number of people is reached.
      // TODO : change the status of the form and not add this submission
      $webform->setStatus(WebformInterface::STATUS_CLOSED);
      $webform->save();
      $log_message = "The form is full, so it's now closed, but normally it should already have been closed!?";

    } elseif ( $event_max_people == $current_reserved + $webform_submission->getElementData('number_of_people')) {
      // just the number of people to close the registrations
      // TODO : So change form status to close and add the submission.
      $webform->setStatus(false);
      $webform->save();
      $log_message = "The form is full, so it's now closed. From " .$current_reserved. "/" .$event_max_people. " to ".($current_reserved+$webform_submission->getElementData('number_of_people')). "/" .$event_max_people . ".";

    } elseif ($event_max_people < $current_reserved + $webform_submission->getElementData('nombre_de_personnes')) {
      // Not enough places
      // TODO : No submission and go back to the form with a message
      $log_message = "There are only " . ($event_max_people-$current_reserved) ." places left so not enough for your ".$webform_submission->getElementData('number_of_people') ." requested places !";

    } else {
      // everything is ok, so nothing to do, only a message in the log
      $log_message = "The form had " .$current_reserved. "/" .$event_max_people. " people, and now, it has : ".($current_reserved+$webform_submission->getElementData('number_of_people')). "/" .$event_max_people . " people.";
    }

//log the output to the drupal logger, to indicate if the webform is still open or closed after each submission.
    \Drupal::logger('webform_reservations')->info($log_message);
  }
}

I have a problem how to change the status ? I have try :

    $webform->setStatus(false);
    $webform->save();
    
    //or
    
    $webform->setStatus(WebformInterface::STATUS_CLOSED);
    $webform->save();

    //but each time I have the error : 

    Drupal\webform\WebformException : eventVoyage webform [event_voyage] has overridden settings and/or properties and can not be saved. dans Drupal\webform\Entity\Webform->preSave() (ligne 2296 de /var/www/html/web/modules/contrib/webform/src/Entity/Webform.php).
cn flag
Please ask only one question per post. The reason for asking only one question is because *Drupal Answers* has the concept of an "accepted answer". If user A answers question #1 and user B answers question #2, there is no good way to choose which answer should be accepted.
Ludo Parazoom avatar
cn flag
OK I edit the question
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.