I am wondering whether it's possible to programmatically auto-submit a Webform after visiting its URL and to save the user from a 'submit' button click.
The below webform can be accessed via /form/my-invoices
:
and has 3 elements:
- Key: invoice_number
- Key: amount
- Key: seller_name
Use Case:
I have paper invoice with a printed barcode and a barcode reader device.
When a user will scan the barcode on the paper invoice, The barcode result will be generated and the user will be redirected to:
www.example.com/form/my-invoices?invoice_number=123456789&amount=1200&seller_name:john-smith
I want to auto-submit the Webform when the above link will be visited !
So in steps, below what will really happen:
- A user will scan the barcode.
- Barcode will then redirect the user to
www.example.com/form/my-invoices?invoice_number=123456789&amount=1200&seller_name:john-smith
- AUTOMATICALLY, the elements of the webform (form/my-invoices) will be populated from the link query parameter and the webform will be auto-submitted without having the user to click on the "Submit" button.
- After auto submit of the webform, the user will be redirected to:
/specific-url
and with a confirmation message something similar to: "the webform has been auto-submitted on your behalf".
So in summary, how to programmatically auto-submit a webform when the webform url with query parameters is visited ?
Thanks!
UPDATE #2 (edit #2):
After changing the route path to: /form/my-invoices/autosubmit
and visit that page, the webform is indeed successfully submitted by there is no value validation occured:
autosubmit_barcode_results.routing.yml
autosubmit_barcode_results.autosubmitform:
path: '/form/my-invoices/autosubmit'
defaults:
_controller: '\Drupal\autosubmit_barcode_results\Controller\AutoSubmitBarcodeController::autosubmitform'
requirements:
_permission: 'access content'
AutoSubmitBarcodeController.php
<?php
namespace Drupal\autosubmit_barcode_results\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\webform\Entity\Webform;
use Drupal\webform\WebformSubmissionForm;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
class AutoSubmitBarcodeController extends ControllerBase {
/**
* Display the markup.
*
* @return array
*/
public function autosubmitform() {
// Get and prepare variables.
$request = Request::createFromGlobals();
$invoive_number = $request->query->get('invoive_number');
// Get submission values and data.
$values = [
'webform_id' => 'my_invoices',
'entity_type' => NULL,
'entity_id' => NULL,
'in_draft' => FALSE,
'uid' => '1',
'langcode' => 'en',
'token' => 'pgmJREX2l4geg2RGFp0p78Qdfm1ksLxe6IlZ-mN9GZI',
'uri' => '/webform/my_invoices/api',
'remote_addr' => '',
'data' => [
'invoice_number' => $invoice_number,
],
];
// Validate submission.
$errors = WebformSubmissionForm::validateFormValues($values);
// Check there are no validation errors.
if (!empty($errors)) {
$message = $errors['invoice_number'];
$message = drupal_set_message($message, 'error');
return $message;
}
else {
// If no validation errors, then Submit values and get submission ID.
$webform_submission = WebformSubmissionForm::submitFormValues($values);
// Redirect the user.
return new RedirectResponse('/all-my-scanned-invoices');
// Show a success message to the user on the redirected page.
$mesagesuccess = 'New invoice has been successfully scanned.';
$mesagesuccess = drupal_set_message($mesagesuccess, 'status');
return $mesagesuccess;
}
}
}
However when an invoice is scanned twice, the $error
is being displayed properly but along with another error:
You have already scanned this invoice once, please scan another one!
User error: "0" is an invalid render array key in Drupal\Core\Render\Element::children() (line 97 of core\lib\Drupal\Core\Render\Element.php).
Drupal\Core\Render\Element::children(Array, 1) (Line: 408)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 450)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 226)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 582)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 227)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 117)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object) (Line: 156)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 693)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)