function webform_serial_webform_submission_presave in Webform Serial 7
Implements hook_webform_submission_presave().
File
- components/
serial.inc, line 178 - Webform module serial component.
Code
function webform_serial_webform_submission_presave($node, &$submission) {
foreach ($node->webform['components'] as $cid => $component) {
// If component is a serial number with no value, generate a value.
if ($component['type'] === 'serial' && empty($submission->data[$cid][0])) {
// Calculate the increment (default to 1).
$increment = empty($component['extra']['increment']) ? 1 : (int) $component['extra']['increment'];
// Get largest serial number in the database to ensure the new one is larger.
$query = db_select('webform_submitted_data')
->condition('nid', $node->nid)
->condition('cid', $cid);
// CAST() is needed because value is stored as text but must be sorted as a number.
// Must CAST() to "decimal" because MySQL does not support "integer".
$query
->addExpression('MAX(CAST(data AS decimal))');
$current_max = (int) $query
->execute()
->fetchField();
// Use a transaction with SELECT ... FOR UPDATE to lock the row between
// the SELECT and the UPDATE, ensuring that multiple Webform submissions
// at the same time do not have duplicate numbers.
$txn = db_transaction();
// Get the next serial number as configured in the component.
$component_extra = db_select('webform_component', 'wc')
->forUpdate()
->fields('wc', array(
'extra',
))
->condition('nid', $node->nid)
->condition('cid', $cid)
->execute()
->fetchField();
$component_extra = unserialize($component_extra);
$next_value = empty($component['extra']['initial']) ? 1 : $component['extra']['initial'];
// If the next value is smaller than the largest value currently in the
// database, increment the largest value and use that as the next value.
if ($next_value <= $current_max) {
$next_value = $current_max + $increment;
}
// Increment the next value and save it in the database.
$component_extra['initial'] = $next_value + $increment;
db_update('webform_component')
->fields(array(
'extra' => serialize($component_extra),
))
->condition('nid', $node->nid)
->condition('cid', $cid)
->execute();
$submission->data[$cid] = array(
$next_value,
);
}
}
}