Commit | Line | Data |
---|---|---|
6296d794 | 1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
4 | | Copyright CiviCRM LLC. All rights reserved. | | |
5 | | | | |
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 | | |
9 | +--------------------------------------------------------------------+ | |
10 | */ | |
11 | ||
12 | /** | |
13 | * | |
14 | * @package CRM | |
15 | * @copyright CiviCRM LLC https://civicrm.org/licensing | |
16 | */ | |
17 | ||
18 | /** | |
19 | * Redirects a user to the full url from a mailing url. | |
5c9b70e5 TO |
20 | * |
21 | * General Usage: civicrm/mailing/url?qid={event_queue_id}&u={url_id} | |
22 | * | |
23 | * Additional arguments may be handled by extractPassthroughParameters(). | |
6296d794 | 24 | */ |
25 | class CRM_Mailing_Page_Url extends CRM_Core_Page { | |
26 | ||
27 | /** | |
28 | * Redirect the user to the specified url. | |
29 | * | |
30 | * @throws \CRM_Core_Exception | |
31 | */ | |
32 | public function run() { | |
33 | $queue_id = CRM_Utils_Request::retrieveValue('qid', 'Integer'); | |
34 | $url_id = CRM_Utils_Request::retrieveValue('u', 'Integer', NULL, TRUE); | |
a3d16f1e | 35 | $url = trim(CRM_Mailing_Event_BAO_TrackableURLOpen::track($queue_id, $url_id)); |
5c9b70e5 | 36 | $query_string = $this->extractPassthroughParameters(); |
6296d794 | 37 | |
38 | if (strlen($query_string) > 0) { | |
39 | // Parse the url to preserve the fragment. | |
40 | $pieces = parse_url($url); | |
41 | ||
42 | if (isset($pieces['fragment'])) { | |
43 | $url = str_replace('#' . $pieces['fragment'], '', $url); | |
44 | } | |
45 | ||
46 | // Handle additional query string params. | |
47 | if ($query_string) { | |
48 | if (stristr($url, '?')) { | |
49 | $url .= '&' . $query_string; | |
50 | } | |
51 | else { | |
52 | $url .= '?' . $query_string; | |
53 | } | |
54 | } | |
55 | ||
56 | // slap the fragment onto the end per URL spec | |
57 | if (isset($pieces['fragment'])) { | |
58 | $url .= '#' . $pieces['fragment']; | |
59 | } | |
60 | } | |
78e62e18 TO |
61 | CRM_Utils_System::redirect($url, [ |
62 | 'for' => 'civicrm/mailing/url', | |
63 | 'queue_id' => $queue_id, | |
64 | 'url_id' => $url_id, | |
65 | ]); | |
6296d794 | 66 | } |
67 | ||
5c9b70e5 TO |
68 | /** |
69 | * Determine if this request has any valid pass-through parameters. | |
70 | * | |
71 | * Under CRM-7103 (v3.3), all unrecognized query-parameters (besides qid/u) are passed | |
72 | * through as part of the redirect. This mechanism is relevant to certain | |
73 | * customizations (eg using `hook_alterMailParams` to append extra URL args) | |
74 | * but does not matter for normal URLs. | |
75 | * | |
76 | * The functionality seems vaguely problematic (IMHO) - especially now that | |
77 | * 'extern/url.php' is moving into the CMS/Civi router ('civicrm/mailing/url'). | |
78 | * But it's the current protocol. | |
79 | * | |
80 | * A better design might be to support `hook_alterRedirect` in the CiviMail | |
81 | * click-through tracking. Then you don't have to take any untrusted inputs | |
82 | * and you can fix URL mistakes in realtime. | |
83 | * | |
84 | * @return string | |
85 | * @link https://issues.civicrm.org/jira/browse/CRM-7103 | |
86 | */ | |
87 | protected function extractPassthroughParameters():string { | |
92daae85 TO |
88 | $config = CRM_Core_Config::singleton(); |
89 | ||
5c9b70e5 | 90 | $query_param = $_GET; |
92daae85 TO |
91 | unset($query_param['qid']); |
92 | unset($query_param['u']); | |
93 | unset($query_param[$config->userFrameworkURLVar]); | |
c6fa8da8 SL |
94 | |
95 | // @see dev/core#1865 for some additional query strings we need to remove as well. | |
92daae85 TO |
96 | if ($config->userFramework === 'WordPress') { |
97 | // Ugh | |
98 | unset($query_param['page']); | |
99 | unset($query_param['noheader']); | |
c6fa8da8 SL |
100 | unset($query_param['civiwp']); |
101 | } | |
102 | elseif ($config->userFramework === 'Joomla') { | |
103 | unset($query_param['option']); | |
92daae85 TO |
104 | } |
105 | ||
5c9b70e5 TO |
106 | $query_string = http_build_query($query_param); |
107 | return $query_string; | |
108 | } | |
109 | ||
6296d794 | 110 | } |