22
33/**
44 * @file
5- * Install, update and uninstall functions for the bay-platform-dependencies module.
5+ * Install, update, uninstall functions for bay-platform-dependencies module.
66 */
77
88use Drush\Drush;
@@ -22,20 +22,20 @@ function bay_platform_dependencies_uninstall() {
2222}
2323
2424/**
25- * Update section purger plugin to sectionbundled
25+ * Update section purger plugin to sectionbundled.
2626 */
2727function bay_platform_dependencies_update_10001() {
2828 $config_factory = \Drupal::configFactory();
2929
30- // Update section purger plugin settings
30+ // Update section purger plugin settings.
3131 $purge_plugins_config = $config_factory->getEditable('purge.plugins');
3232 $purgers = $purge_plugins_config->get('purgers');
3333
3434 if (is_array($purgers)) {
3535 foreach ($purgers as &$purger) {
36- // Only update plugin_id for section purger
36+ // Only update plugin_id for section purger.
3737 if (isset($purger['plugin_id']) && $purger['plugin_id'] === "section") {
38- // Update the plugin_id to section bundled
38+ // Update the plugin_id to section bundled.
3939 $purger['plugin_id'] = 'sectionbundled';
4040 $purge_plugins_config->set('purgers', $purgers);
4141 $purge_plugins_config->save();
@@ -44,15 +44,15 @@ function bay_platform_dependencies_update_10001() {
4444 }
4545 }
4646
47- // Update section purger logger channels settings
47+ // Update section purger logger channels settings.
4848 $purge_logger_channels_config = $config_factory->getEditable('purge.logger_channels');
4949 $channels = $purge_logger_channels_config->get('channels');
5050 if (is_array($channels)) {
5151 foreach ($channels as &$channel) {
52- // Only update channel id for section purger
52+ // Only update channel id for section purger.
5353 if (isset($channel['id']) && strpos($channel['id'], "purger_section_") === 0) {
5454 // Update the id to section bundled
55- // channel id is in the format of purger_section_{purger_id}
55+ // channel id is in the format of purger_section_{purger_id}.
5656 $parts = explode('_', $channel['id']);
5757 $purger_id = end($parts);
5858 $channel['id'] = "purger_sectionbundled_{$purger_id}";
@@ -97,4 +97,200 @@ function bay_platform_dependencies_update_10003() {
9797function bay_platform_dependencies_update_10004() {
9898 $process = Drush::drush(Drush::aliasManager()->getSelf(), 'section_purger:install_sensor');
9999 $process->run();
100- }
100+ }
101+
102+ /**
103+ * Fix webform email handler configurations.
104+ *
105+ * - Ensures valid values for from_mail, return_path, and sender_mail fields.
106+ * - Preserves original from_mail in reply_to.
107+ */
108+ function bay_platform_dependencies_update_10005(&$sandbox) {
109+ $message = [];
110+ $translation = \Drupal::translation();
111+
112+ // Initialize batch processing if this is the first pass.
113+ if (!isset($sandbox['progress'])) {
114+ $sandbox['progress'] = 0;
115+ $sandbox['current_id'] = 0;
116+ $sandbox['max'] = \Drupal::entityTypeManager()->getStorage('webform')->getQuery()->count()->execute();
117+
118+ // If there are no webforms, return immediately.
119+ if ($sandbox['max'] == 0) {
120+ $message[] = $translation->translate('No webforms found to update.');
121+ return $message;
122+ }
123+
124+ // Initialize counters.
125+ $sandbox['fixed_count'] = 0;
126+ $sandbox['webforms_processed'] = 0;
127+ }
128+
129+ // List of valid values for the settings.
130+ $validValues = ['[site:mail]', '', '_default'];
131+
132+ // Add values from SMTP_FROM_WHITELIST environment variable if it exists.
133+ $whitelist = getenv('SMTP_FROM_WHITELIST');
134+ if ($whitelist) {
135+ $whitelistEmails = explode(',', $whitelist);
136+ // Trim whitespace from each email.
137+ $whitelistEmails = array_map('trim', $whitelistEmails);
138+ // Add whitelisted emails to valid values.
139+ $validValues = array_merge($validValues, $whitelistEmails);
140+ $message[] = $translation->translate('Added @count email addresses from SMTP_FROM_WHITELIST to valid values.',
141+ ['@count' => count($whitelistEmails)]);
142+ }
143+
144+ // Process webforms in chunks.
145+ // Number of webforms to process per batch.
146+ $limit = 20;
147+ $webform_ids = \Drupal::entityTypeManager()->getStorage('webform')
148+ ->getQuery()
149+ ->condition('id', $sandbox['current_id'], '>')
150+ ->sort('id')
151+ ->range(0, $limit)
152+ ->execute();
153+
154+ if (empty($webform_ids)) {
155+ // If no webforms were found, we're done.
156+ $sandbox['#finished'] = 1;
157+ return $message;
158+ }
159+
160+ $webforms = \Drupal::entityTypeManager()->getStorage('webform')->loadMultiple($webform_ids);
161+
162+ foreach ($webforms as $webform) {
163+ $webformName = $webform->label();
164+ $webformId = $webform->id();
165+ $webformChanged = FALSE;
166+
167+ // Get email handlers from the webform.
168+ $handlers = $webform->getHandlers();
169+
170+ foreach ($handlers as $handler) {
171+ // Check if it's an email handler.
172+ if ($handler->getPluginId() === 'email') {
173+ $configuration = $handler->getConfiguration();
174+ $settings = &$configuration['settings'];
175+ $handlerChanged = FALSE;
176+
177+ $handlerLabel = $handler->getLabel();
178+
179+ // Check if return_path is not in the valid values list.
180+ if (isset($settings['return_path']) && !in_array($settings['return_path'], $validValues)) {
181+ $message[] = $translation->translate(
182+ 'Webform: @name (ID: @id), Email Handler: @handler, return_path is set to "@value" instead of a valid value',
183+ [
184+ '@name' => $webformName,
185+ '@id' => $webformId,
186+ '@handler' => $handlerLabel,
187+ '@value' => $settings['return_path'],
188+ ],
189+ );
190+
191+ // Set return_path to empty string.
192+ $oldValue = $settings['return_path'];
193+ $settings['return_path'] = '';
194+ $message[] = $translation->translate(' - FIXED: Changed return_path from "@old" to ""', ['@old' => $oldValue]);
195+ $handlerChanged = TRUE;
196+ $sandbox['fixed_count']++;
197+ }
198+
199+ // Check if sender_mail is not in the valid values list.
200+ if (isset($settings['sender_mail']) && !in_array($settings['sender_mail'], $validValues)) {
201+ $message[] = $translation->translate(
202+ 'Webform: @name (ID: @id), Email Handler: @handler, sender_mail is set to "@value" instead of a valid value',
203+ [
204+ '@name' => $webformName,
205+ '@id' => $webformId,
206+ '@handler' => $handlerLabel,
207+ '@value' => $settings['sender_mail'],
208+ ],
209+ );
210+
211+ // Set sender_mail to empty string.
212+ $oldValue = $settings['sender_mail'];
213+ $settings['sender_mail'] = '';
214+ $message[] = $translation->translate(' - FIXED: Changed sender_mail from "@old" to ""', ['@old' => $oldValue]);
215+ $handlerChanged = TRUE;
216+ $sandbox['fixed_count']++;
217+ }
218+
219+ // Check if from_mail is not in the valid values list and fix it by
220+ // setting to '_default'.
221+ if (isset($settings['from_mail']) && !in_array($settings['from_mail'], $validValues)) {
222+ $message[] = $translation->translate(
223+ 'Webform: @name (ID: @id), Email Handler: @handler, from_mail is set to "@value" instead of a valid value',
224+ [
225+ '@name' => $webformName,
226+ '@id' => $webformId,
227+ '@handler' => $handlerLabel,
228+ '@value' => $settings['from_mail'],
229+ ],
230+ );
231+
232+ // Store the current from_mail value before changing it.
233+ $oldFromMail = $settings['from_mail'];
234+
235+ // Set from_mail to '_default'.
236+ $settings['from_mail'] = '_default';
237+ $message[] = $translation->translate(' - FIXED: Changed from_mail from "@old" to "_default"', ['@old' => $oldFromMail]);
238+
239+ // Also update reply_to to preserve the original email for replies.
240+ $oldReplyTo = $settings['reply_to'] ?? '';
241+ $settings['reply_to'] = $oldFromMail;
242+ $message[] = $translation->translate(' - UPDATED: Set reply_to from "@old" to "@new"', [
243+ '@old' => $oldReplyTo,
244+ '@new' => $oldFromMail,
245+ ]);
246+
247+ $handlerChanged = TRUE;
248+ $sandbox['fixed_count']++;
249+ }
250+
251+ // Update the handler configuration if changes were made.
252+ if ($handlerChanged) {
253+ $handler->setConfiguration($configuration);
254+ $webformChanged = TRUE;
255+ }
256+ }
257+ }
258+
259+ // Save the webform if any handlers were updated.
260+ if ($webformChanged) {
261+ $webform->save();
262+ $message[] = $translation->translate('Saved changes to webform: @name (ID: @id)', [
263+ '@name' => $webformName,
264+ '@id' => $webformId,
265+ ]);
266+ }
267+
268+ // Update progress information.
269+ $sandbox['progress']++;
270+ $sandbox['webforms_processed']++;
271+ $sandbox['current_id'] = $webformId;
272+ }
273+
274+ // Set the value for finished. If there are no webforms, we're done.
275+ $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);
276+
277+ // If we're done, provide a summary message.
278+ if ($sandbox['#finished'] >= 1) {
279+ if ($sandbox['fixed_count'] > 0) {
280+ $message[] = $translation->translate('Summary: Fixed @count issues with the following settings:', ['@count' => $sandbox['fixed_count']]);
281+ $message[] = $translation->translate('- return_path and sender_mail set to "" (empty string)');
282+ $message[] = $translation->translate('- from_mail set to "_default" and moved original from_mail value to reply_to');
283+
284+ $validValuesList = "'[site:mail]', '' (empty string), '_default'";
285+ if ($whitelist) {
286+ $validValuesList .= ', and whitelisted emails from SMTP_FROM_WHITELIST';
287+ }
288+ $message[] = $translation->translate('Valid values include: @values.', ['@values' => $validValuesList]);
289+ }
290+ else {
291+ $message[] = $translation->translate('No issues found. All email handlers in webforms have correct return_path, sender_mail, and from_mail settings.');
292+ }
293+ }
294+
295+ return implode("\n", $message);
296+ }
0 commit comments