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).