Merge in 5.20
[civicrm-core.git] / CRM / Utils / Verp.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 5 | |
bc77d7c0
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035
TO
11
12/**
13 * Class to handle encoding and decoding Variable Enveleope Return Path (VERP)
14 * headers.
15 *
16 * @package CRM
ca5cec67 17 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035
TO
18 */
19class CRM_Utils_Verp {
6714d8d2
SL
20 /**
21 * Mapping of reserved characters to hex codes
22 * @var array
23 */
24 public static $encodeMap = [
6a488035
TO
25 '+' => '2B',
26 '@' => '40',
27 ':' => '3A',
28 '%' => '25',
29 '!' => '21',
30 '-' => '2D',
31 '[' => '5B',
32 ']' => '5D',
be2fb01f 33 ];
6a488035 34
6714d8d2
SL
35 /**
36 * Mapping of hex codes to reserved characters
37 * @var array
38 */
39 public static $decodeMap = [
6a488035
TO
40 '40' => '@',
41 '3A' => ':',
42 '25' => '%',
43 '21' => '!',
44 '2D' => '-',
45 '5B' => '[',
46 '5D' => ']',
47 '2B' => '+',
be2fb01f 48 ];
6a488035
TO
49
50 /**
51 * Encode the sender's address with the VERPed recipient.
52 *
77855840
TO
53 * @param string $sender
54 * The address of the sender.
55 * @param string $recipient
56 * The address of the recipient.
6a488035 57 *
a6c01b45
CW
58 * @return string
59 * The VERP encoded address
6a488035
TO
60 */
61 public static function encode($sender, $recipient) {
62 preg_match('/(.+)\@([^\@]+)$/', $sender, $match);
63 $slocal = $match[1];
64 $sdomain = $match[2];
65
66 preg_match('/(.+)\@([^\@]+)$/', $recipient, $match);
67 $rlocal = CRM_Utils_Array::value(1, $match);
68 $rdomain = CRM_Utils_Array::value(2, $match);
69
70 foreach (self::$encodeMap as $char => $code) {
71 $rlocal = preg_replace('/' . preg_quote($char) . '/i', "+$code", $rlocal);
72 $rdomain = preg_replace('/' . preg_quote($char) . '/i', "+$code", $rdomain);
73 }
74
75 return "$slocal-$rlocal=$rdomain@$sdomain";
76 }
77
78 /**
fe482240 79 * Decode the address and return the sender and recipient as an array.
6a488035 80 *
77855840
TO
81 * @param string $address
82 * The address to be decoded.
6a488035 83 *
a6c01b45
CW
84 * @return array
85 * The tuple ($sender, $recipient)
6a488035
TO
86 */
87 public static function &verpdecode($address) {
88 preg_match('/^(.+)-([^=]+)=([^\@]+)\@(.+)/', $address, $match);
89
353ffa53
TO
90 $slocal = $match[1];
91 $rlocal = $match[2];
6a488035
TO
92 $rdomain = $match[3];
93 $sdomain = $match[4];
94
95 foreach (self::$decodeMap as $code => $char) {
96 $rlocal = preg_replace("/+$code/i", $char, $rlocal);
97 $rdomain = preg_replace("/+$code/i", $char, $rdomain);
98 }
99
be2fb01f 100 return ["$slocal@$sdomain", "$rlocal@$rdomain"];
6a488035 101 }
96025800 102
6a488035 103}