From 58e8ae0759ccfa97c478ccae4e0778bdce70966f Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Thu, 22 Jan 2026 22:40:02 +0000
Subject: [PATCH] =DirectoryManager.php updates, some javascript tweaks for CRUD.js, and minor style changes
---
inc/rest/routes/FormRoutes.php | 170 ++++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 132 insertions(+), 38 deletions(-)
diff --git a/inc/rest/routes/FormRoutes.php b/inc/rest/routes/FormRoutes.php
index 1201a8e..c5c0d36 100644
--- a/inc/rest/routes/FormRoutes.php
+++ b/inc/rest/routes/FormRoutes.php
@@ -142,7 +142,6 @@
{
// Get form configuration
$form_config = FormBlock::getForm($form_type);
-
if (!$form_config) {
return new WP_Error('invalid_form', 'Form configuration not found.');
}
@@ -178,7 +177,6 @@
try {
$email_sent = $this->sendEmailNotification($form_type, $form_config, $processed_data, $files);
} catch (\Exception $e) {
- ;
return new WP_Error('email_failed', 'Email error: ' . $e->getMessage());
}
@@ -226,7 +224,7 @@
$value = $normalized_form_data[$field_name] ?? '';
if (in_array($field_config['type'], ['checkbox', 'set'])) {
- $value = jvbCommaList((is_array($value)) ? $value : explode(',',$value));
+ $value = is_array($value) ? implode(',', $value) : $value;
}
// Check required fields
@@ -267,9 +265,6 @@
/**
* Send email notification
*/
- /**
- * Send email notification
- */
protected function sendEmailNotification(string $form_type, array $form_config, array $form_data, array $files = []): bool
{
$admin_email = apply_filters('jvb_form_email_to', $form_config['email_to'], $form_type, $form_data);
@@ -286,6 +281,17 @@
$submitter_name = $form_data['name'];
}
+ if (!array_key_exists('preheader', $form_config)) {
+ $preheader = $form_config['preheader'];
+ } else {
+ $preheader = sprintf(
+ 'New %s submission from %s',
+ $form_config['title'],
+ $submitter_name ?: ($submitter_name ?: 'website visitor')
+ );
+ }
+
+
// Email headers
$headers = [];
@@ -319,23 +325,36 @@
);
}
- // Build form data array for table
+ // Build form data array for table - using similar logic to JS
+ $skip_fields = array_merge(
+ ['sendAll', 'action', 'form_id', 'form_type', 'timestamp', '_wpnonce', '_wp_http_referer', 'cf-turnstile-response'],
+ $form_config['ignore'] ?? []
+ );
+
$form = [];
foreach ($form_config['fields'] as $field_name => $config) {
- // Skip file upload fields
- if ($config['type'] == 'upload') {
+ // Skip ignored fields
+ if (in_array($field_name, $skip_fields)) {
+ continue;
+ }
+
+ // Skip upload fields (handled separately)
+ if ($config['type'] === 'upload') {
continue;
}
$value = $form_data[$field_name] ?? '';
// Skip empty fields
- if (empty($value)) {
+ if ($this->isEmptyValue($value)) {
continue;
}
+ // Get label - check for summaryTitle first, then label (similar to JS checking legend then label)
+ $label = $config['summaryTitle'] ?? $config['label'] ?? ucfirst(str_replace('_', ' ', $field_name));
+
$form[] = [
- 'label' => $config['summaryTitle'] ?? $config['label'],
+ 'label' => $label,
'value' => $this->formatFieldValueForEmail($field_name, $value, $config)
];
}
@@ -359,17 +378,34 @@
$subject,
$body,
'',
+ $preheader,
$headers,
$attachments
);
}
/**
+ * Check if value is empty (similar to JS isEmptyValue)
+ */
+ protected function isEmptyValue($value): bool
+ {
+ if ($value === null || $value === '' || $value === false) {
+ return true;
+ }
+
+ if (is_array($value) && empty($value)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
* Format field value for email display
*/
protected function formatFieldValueForEmail(string $field_name, mixed $value, array $field_config): string
{
- if (empty($value)) {
+ if ($this->isEmptyValue($value)) {
return '';
}
@@ -377,9 +413,17 @@
$type = $field_config['subType'] ?? $type;
switch ($type) {
+ case 'repeater':
+ return $this->formatRepeaterForEmail($value, $field_config);
+
+ case 'tag-list':
+ return $this->formatTagListForEmail($value);
+
+ case 'location':
+ return $this->formatLocationForEmail($value);
+
case 'phone':
case 'tel':
- // Format phone number as xxx-xxx-xxxx
$cleaned = preg_replace('/\D/', '', $value);
if (strlen($cleaned) === 10) {
return substr($cleaned, 0, 3) . '-' . substr($cleaned, 3, 3) . '-' . substr($cleaned, 6);
@@ -388,51 +432,101 @@
case 'checkbox':
case 'set':
- // Convert array of values to comma-separated labels
- if (!is_array($value)) {
- $value = explode(',', $value);
- }
- $labels = [];
- foreach ($value as $val) {
+ $values = explode(',', $value);
+ $labels = array_map(function($val) use ($field_config) {
$val = trim($val);
- if (isset($field_config['options'][$val])) {
- $labels[] = $field_config['options'][$val];
- } else {
- $labels[] = $val; // Fallback to value if no label found
- }
- }
+ return $field_config['options'][$val] ?? ucfirst(str_replace('_', ' ', $val));
+ }, $values);
return implode(', ', $labels);
case 'radio':
case 'select':
- // Return label instead of value
if (isset($field_config['options'][$value])) {
return $field_config['options'][$value];
}
- return $value;
-
- case 'textarea':
- case 'wysiwyg':
- // Keep line breaks for email display
- return $value; // nl2br is already applied in the email body
+ // Fallback: capitalize the value
+ return ucfirst(str_replace('_', ' ', $value));
case 'true_false':
$true_text = $field_config['true_text'] ?? 'Yes';
$false_text = $field_config['false_text'] ?? 'No';
return ($value === '1' || $value === 1 || $value === true) ? $true_text : $false_text;
- case 'email':
- return $value; // Will be clickable in email client
-
- case 'url':
- return $value; // Will be clickable in email client
-
default:
return is_array($value) ? implode(', ', $value) : $value;
}
}
/**
+ * Format repeater field for email
+ */
+ protected function formatRepeaterForEmail(array $rows, array $field_config): string
+ {
+ $output = '';
+
+ foreach ($rows as $index => $row) {
+ $output .= '<strong>Entry ' . ($index + 1) . ':</strong><br>';
+
+ foreach ($row as $sub_field => $sub_value) {
+ if ($this->isEmptyValue($sub_value)) {
+ continue;
+ }
+
+ // Get sub-field label if available
+ $sub_config = $field_config['sub_fields'][$sub_field] ?? [];
+ $label = $sub_config['label'] ?? ucfirst(str_replace('_', ' ', $sub_field));
+
+ $output .= ' ' . esc_html($label) . ': ' . esc_html($sub_value) . '<br>';
+ }
+
+ $output .= '<br>';
+ }
+
+ return $output;
+ }
+
+ /**
+ * Format tag-list field for email
+ */
+ protected function formatTagListForEmail(array $tags): string
+ {
+ $items = [];
+
+ foreach ($tags as $tag) {
+ // Get first non-empty value as display
+ $display = '';
+ foreach ($tag as $field => $value) {
+ if (!$this->isEmptyValue($value)) {
+ $display = $value;
+ break;
+ }
+ }
+
+ if ($display) {
+ $items[] = $display;
+ }
+ }
+
+ return implode(', ', $items);
+ }
+
+ /**
+ * Format location field for email
+ */
+ protected function formatLocationForEmail(array $location): string
+ {
+ $parts = [];
+
+ if (!empty($location['street'])) $parts[] = $location['street'];
+ if (!empty($location['city'])) $parts[] = $location['city'];
+ if (!empty($location['province'])) $parts[] = $location['province'];
+ if (!empty($location['postal_code'])) $parts[] = $location['postal_code'];
+ if (!empty($location['country'])) $parts[] = $location['country'];
+
+ return !empty($parts) ? implode(', ', $parts) : ($location['address'] ?? '');
+ }
+
+ /**
* Process uploaded files for email attachments
* Files are in PHP's tmp directory and will be automatically cleaned up after request
*/
--
Gitblit v1.10.0