Skip to content

Commit 3a24840

Browse files
committed
feat(vendor_detection): enhance data request handling with controller domain matching and UI improvements
1 parent 47dc694 commit 3a24840

File tree

4 files changed

+141
-121
lines changed

4 files changed

+141
-121
lines changed

modules/imap/handler_modules.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1996,6 +1996,15 @@ public function process() {
19961996
$vendor_detection = vendor_detection_detect_sender($msg_headers, $msg_source, $vendor_registry);
19971997
$data_request_match = vendor_detection_match_data_request($vendor_detection, $msg_headers);
19981998
if (defined('DEBUG_MODE') && DEBUG_MODE) {
1999+
$controller_domains = vendor_detection_get_controller_domains($msg_headers, $vendor_detection);
2000+
error_log('[data_request_match_handler_debug] '.json_encode(array(
2001+
'imap_server_id' => $form['imap_server_id'],
2002+
'folder' => $form['folder'],
2003+
'uid' => $form['imap_msg_uid'],
2004+
'controller_domains' => $controller_domains,
2005+
'vendor_id' => $vendor_detection['vendor_id'] ?? '',
2006+
'platform_domains' => $vendor_detection['platform_domains'] ?? array()
2007+
)));
19992008
error_log('[vendor_detection] '.json_encode(array(
20002009
'imap_server_id' => $form['imap_server_id'],
20012010
'folder' => $form['folder'],

modules/vendor_detection/functions.php

Lines changed: 103 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,34 @@ function vendor_detection_match_data_request($vendor_detection, $msg_headers, $r
552552
}
553553
}
554554

555+
if (!empty($controller_domains)) {
556+
if (!empty($entities)) {
557+
foreach ($controller_domains as $controller_domain) {
558+
foreach ($entities as $entity) {
559+
$match = vendor_detection_match_entity_domain_fallback($entity, $controller_domain);
560+
if ($match) {
561+
if (defined('DEBUG_MODE') && DEBUG_MODE) {
562+
error_log('[data_request_match_debug] matched controller domain fallback');
563+
}
564+
return $match;
565+
}
566+
}
567+
}
568+
} else {
569+
foreach ($controller_domains as $controller_domain) {
570+
foreach ($companies as $entry) {
571+
$match = vendor_detection_match_data_request_domain_fallback($entry, $controller_domain);
572+
if ($match) {
573+
if (defined('DEBUG_MODE') && DEBUG_MODE) {
574+
error_log('[data_request_match_debug] matched controller domain fallback');
575+
}
576+
return $match;
577+
}
578+
}
579+
}
580+
}
581+
}
582+
555583
if (!empty($entities)) {
556584
foreach ($entities as $entity) {
557585
$match = vendor_detection_match_entity_vendor($entity, $vendor_id, $platform_domains);
@@ -599,8 +627,12 @@ function vendor_detection_match_data_request_entry($entry, $controller_domain, $
599627
return array();
600628
}
601629

602-
if ($controller_domain && in_array($controller_domain, $domains, true)) {
603-
return vendor_detection_build_data_request_match($entry, 'controller_domain', $controller_domain, array());
630+
if ($controller_domain) {
631+
foreach ($domains as $domain) {
632+
if (vendor_detection_domain_matches($controller_domain, $domain)) {
633+
return vendor_detection_build_data_request_match($entry, 'controller_domain', $controller_domain, array());
634+
}
635+
}
604636
}
605637

606638
if ($controller_only) {
@@ -611,9 +643,11 @@ function vendor_detection_match_data_request_entry($entry, $controller_domain, $
611643
return vendor_detection_build_data_request_match($entry, 'vendor_id', $vendor_id, array());
612644
}
613645

614-
foreach ($platform_domains as $domain) {
615-
if (in_array($domain, $domains, true)) {
616-
return vendor_detection_build_data_request_match($entry, 'platform_domain', $domain, array());
646+
foreach ($platform_domains as $platform_domain) {
647+
foreach ($domains as $domain) {
648+
if (vendor_detection_domain_matches($platform_domain, $domain)) {
649+
return vendor_detection_build_data_request_match($entry, 'platform_domain', $platform_domain, array());
650+
}
617651
}
618652
}
619653

@@ -646,8 +680,37 @@ function vendor_detection_match_entity_controller($entity, $controller_domain) {
646680
continue;
647681
}
648682
$domains = vendor_detection_lowercase_list($entry['domains'] ?? array());
649-
if (in_array($controller_domain, $domains, true)) {
650-
return vendor_detection_build_data_request_match($entry, 'controller_domain', $controller_domain, $entity);
683+
foreach ($domains as $domain) {
684+
if (vendor_detection_domain_matches($controller_domain, $domain)) {
685+
return vendor_detection_build_data_request_match($entry, 'controller_domain', $controller_domain, $entity);
686+
}
687+
}
688+
}
689+
return array();
690+
}
691+
}
692+
693+
if (!hm_exists('vendor_detection_match_entity_domain_fallback')) {
694+
function vendor_detection_match_entity_domain_fallback($entity, $controller_domain) {
695+
$entries = $entity['entries'] ?? array();
696+
foreach ($entries as $entry) {
697+
$domains = vendor_detection_lowercase_list($entry['domains'] ?? array());
698+
foreach ($domains as $domain) {
699+
if (vendor_detection_domain_matches($controller_domain, $domain)) {
700+
return vendor_detection_build_data_request_match($entry, 'controller_domain', $controller_domain, $entity);
701+
}
702+
}
703+
}
704+
return array();
705+
}
706+
}
707+
708+
if (!hm_exists('vendor_detection_match_data_request_domain_fallback')) {
709+
function vendor_detection_match_data_request_domain_fallback($entry, $controller_domain) {
710+
$domains = vendor_detection_lowercase_list($entry['domains'] ?? array());
711+
foreach ($domains as $domain) {
712+
if (vendor_detection_domain_matches($controller_domain, $domain)) {
713+
return vendor_detection_build_data_request_match($entry, 'controller_domain', $controller_domain, array());
651714
}
652715
}
653716
return array();
@@ -667,11 +730,13 @@ function vendor_detection_match_entity_vendor($entity, $vendor_id, $platform_dom
667730
}
668731
}
669732

670-
foreach ($platform_domains as $domain) {
733+
foreach ($platform_domains as $platform_domain) {
671734
foreach ($entries as $entry) {
672735
$domains = vendor_detection_lowercase_list($entry['domains'] ?? array());
673-
if (in_array($domain, $domains, true)) {
674-
return vendor_detection_build_data_request_match($entry, 'platform_domain', $domain, $entity);
736+
foreach ($domains as $domain) {
737+
if (vendor_detection_domain_matches($platform_domain, $domain)) {
738+
return vendor_detection_build_data_request_match($entry, 'platform_domain', $platform_domain, $entity);
739+
}
675740
}
676741
}
677742
}
@@ -752,72 +817,46 @@ function vendor_detection_normalize_domain($value) {
752817
}
753818
}
754819

755-
if (!hm_exists('vendor_detection_get_user_email')) {
756-
function vendor_detection_get_user_email($imap_accounts, $server_id) {
757-
if (!is_array($imap_accounts) || !$server_id) {
758-
return '';
759-
}
760-
if (!isset($imap_accounts[$server_id])) {
761-
return '';
820+
if (!hm_exists('vendor_detection_domain_matches')) {
821+
function vendor_detection_domain_matches($value, $domain) {
822+
if (!$value || !$domain) {
823+
return false;
762824
}
763-
$account = $imap_accounts[$server_id];
764-
if (isset($account['user'])) {
765-
return (string) $account['user'];
825+
$value = mb_strtolower($value);
826+
$domain = mb_strtolower($domain);
827+
if ($value === $domain) {
828+
return true;
766829
}
767-
return '';
830+
return substr($value, -1 * (strlen($domain) + 1)) === '.'.$domain;
768831
}
769832
}
770833

771-
if (!hm_exists('vendor_detection_get_profile_name')) {
772-
function vendor_detection_get_profile_name() {
773-
if (!class_exists('Hm_Profiles')) {
774-
return '';
775-
}
776-
$profile = Hm_Profiles::getDefault();
777-
if (!$profile || empty($profile['name'])) {
778-
return '';
834+
if (!hm_exists('vendor_detection_get_datarequests_base_url')) {
835+
function vendor_detection_get_datarequests_base_url($language) {
836+
$language = mb_strtolower((string) $language);
837+
if ($language) {
838+
$parts = preg_split('/[_-]/', $language);
839+
$language = $parts[0] ?? $language;
779840
}
780-
if (mb_strtolower($profile['name']) === 'default') {
781-
return '';
841+
$supported = array('fr', 'de', 'es', 'it');
842+
if ($language && in_array($language, $supported, true)) {
843+
return 'https://'.$language.'.datarequests.org';
782844
}
783-
return (string) $profile['name'];
845+
return 'https://www.datarequests.org';
784846
}
785847
}
786848

787-
if (!hm_exists('vendor_detection_get_message_id')) {
788-
function vendor_detection_get_message_id($msg_headers) {
789-
if (!is_array($msg_headers)) {
849+
if (!hm_exists('vendor_detection_build_datarequests_generator_url')) {
850+
function vendor_detection_build_datarequests_generator_url($company_slug, $request_type, $language) {
851+
if (!$company_slug || !$request_type) {
790852
return '';
791853
}
792-
if (function_exists('lc_headers')) {
793-
$msg_headers = lc_headers($msg_headers);
794-
}
795-
$message_id = $msg_headers['message-id'] ?? '';
796-
if (is_array($message_id)) {
797-
$message_id = $message_id[0] ?? '';
798-
}
799-
return (string) $message_id;
800-
}
801-
}
802-
803-
if (!hm_exists('vendor_detection_build_request_template')) {
804-
function vendor_detection_build_request_template($vendor_name, $user_email, $display_name, $message_id) {
805-
$lines = array();
806-
$lines[] = 'Subject: Data request';
807-
$lines[] = '';
808-
$lines[] = 'Hello '.$vendor_name.',';
809-
$lines[] = '';
810-
$lines[] = 'I am requesting access to the personal data you hold about me.';
811-
$lines[] = 'Please also let me know how I can correct or delete that data, and how to stop direct marketing.';
812-
$lines[] = '';
813-
$lines[] = 'My email address: '.($user_email ? $user_email : '');
814-
$lines[] = 'My name: '.($display_name ? $display_name : '');
815-
if ($message_id) {
816-
$lines[] = 'Reference message ID: '.$message_id;
817-
}
818-
$lines[] = '';
819-
$lines[] = 'Thank you.';
820-
return implode("\n", $lines);
854+
$base_url = vendor_detection_get_datarequests_base_url($language);
855+
$query = http_build_query(array(
856+
'company' => $company_slug,
857+
'request_type' => $request_type
858+
));
859+
return $base_url.'/generator?'.$query;
821860
}
822861
}
823862

modules/vendor_detection/modules.php

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,18 @@ protected function output() {
9494
$data_request_enabled = (bool) $override;
9595
}
9696
}
97-
$has_data_request = $data_request_enabled && !empty($data_request_match['datarequests_url']);
97+
$company_slug = $data_request_match['vendor_id'] ?? '';
98+
$has_data_request = $data_request_enabled && $company_slug;
99+
if (defined('DEBUG_MODE') && DEBUG_MODE) {
100+
error_log('[data_request_ui_debug] '.json_encode(array(
101+
'vendor_name' => $vendor_name_raw,
102+
'has_vendor_label' => $has_vendor_label,
103+
'data_request_enabled' => $data_request_enabled,
104+
'company_slug' => $company_slug,
105+
'has_data_request' => (bool) $has_data_request,
106+
'data_request_match' => $data_request_match
107+
)));
108+
}
98109
if (!$has_vendor_label && !$has_data_request) {
99110
return '';
100111
}
@@ -167,45 +178,29 @@ protected function output() {
167178

168179
$data_request_html = '';
169180
if ($has_data_request) {
170-
$base_url = $this->html_safe($data_request_match['datarequests_url']);
181+
$language = $this->get('language', '');
171182
$request_target = $this->html_safe($data_request_match['vendor_name'] ?? '');
172183
$target_label = $request_target ? $request_target.' ' : '';
184+
$request_types = array(
185+
'access' => $this->trans('Get access to my data'),
186+
'delete' => $this->trans('Delete my data'),
187+
'rectification' => $this->trans('Correct my data'),
188+
'objection' => $this->trans('Stop direct marketing')
189+
);
190+
$links = array();
191+
foreach ($request_types as $request_type => $label) {
192+
$url = vendor_detection_build_datarequests_generator_url($company_slug, $request_type, $language);
193+
if (!$url) {
194+
continue;
195+
}
196+
$links[] = '<a href="'.$this->html_safe($url).'" class="vendor-detection-request-link" '.
197+
'target="_blank" rel="noopener">'.$label.'</a>';
198+
}
173199
$data_request_html = '<div class="vendor-detection-requests">'.
174200
'<span class="vendor-detection-requests-label">'.$this->trans('Data requests').':</span> '.
175201
$target_label.
176-
'<a href="'.$base_url.'" class="vendor-detection-request-link" target="_blank" rel="noopener">'.
177-
$this->trans('Get access to data about me').'</a> '.
178-
'<span class="vendor-detection-request-sep">|</span> '.
179-
'<a href="'.$base_url.'" class="vendor-detection-request-link" target="_blank" rel="noopener">'.
180-
$this->trans('Delete data about me').'</a> '.
181-
'<span class="vendor-detection-request-sep">|</span> '.
182-
'<a href="'.$base_url.'" class="vendor-detection-request-link" target="_blank" rel="noopener">'.
183-
$this->trans('Correct data about me').'</a> '.
184-
'<span class="vendor-detection-request-sep">|</span> '.
185-
'<a href="'.$base_url.'" class="vendor-detection-request-link" target="_blank" rel="noopener">'.
186-
$this->trans('Stop direct marketing').'</a>'.
202+
implode(' <span class="vendor-detection-request-sep">|</span> ', $links).
187203
'</div>';
188-
189-
$imap_accounts = $this->get('imap_accounts', array());
190-
$server_id = $this->get('msg_server_id');
191-
$user_email = vendor_detection_get_user_email($imap_accounts, $server_id);
192-
$display_name = vendor_detection_get_profile_name();
193-
$message_id = vendor_detection_get_message_id($this->get('msg_headers', array()));
194-
$template_name = $vendor_name_raw ?: ($data_request_match['vendor_name'] ?? 'there');
195-
$template = vendor_detection_build_request_template(
196-
$template_name,
197-
$user_email,
198-
$display_name,
199-
$message_id
200-
);
201-
$template_id = 'vendor-detection-template-'.$uid;
202-
$data_request_html .= '<div class="vendor-detection-template">'.
203-
'<button class="vendor-detection-toggle" type="button" data-bs-toggle="collapse" '.
204-
'data-bs-target="#'.$this->html_safe($template_id).'" aria-expanded="false" aria-controls="'.$this->html_safe($template_id).'">'.
205-
// '<i class="bi bi-pencil-square"></i> '.$this->trans('Request template').'</button>'.
206-
'<div class="vendor-detection-template-panel collapse" id="'.$this->html_safe($template_id).'">'.
207-
'<textarea class="vendor-detection-template-text" rows="8">'.$this->html_safe($template).'</textarea>'.
208-
'</div></div>';
209204
}
210205

211206
$requests_wrapper = $data_request_html ? '<div class="vendor-detection-requests-content">'.$data_request_html.'</div>' : '';

modules/vendor_detection/site.css

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -83,29 +83,6 @@
8383
color: #9aa1a9;
8484
}
8585

86-
.vendor-detection-template {
87-
margin-top: 0.35rem;
88-
}
89-
90-
.vendor-detection-template-panel {
91-
margin-top: 0.4rem;
92-
border: 1px solid #e5e7eb;
93-
border-radius: 0.35rem;
94-
background: #f8f9fa;
95-
padding: 0.5rem;
96-
}
97-
98-
.vendor-detection-template-text {
99-
width: 100%;
100-
border: 1px solid #d1d5db;
101-
border-radius: 0.35rem;
102-
padding: 0.45rem;
103-
font-size: 0.85rem;
104-
color: #374151;
105-
background: #fff;
106-
resize: vertical;
107-
}
108-
10986
.vendor-detection-content {
11087
display: flex;
11188
}

0 commit comments

Comments
 (0)