Merge pull request #19463 from colemanw/removeCampaignPseudoconstant
[civicrm-core.git] / CRM / Mailing / Page / Url.php
CommitLineData
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 */
25class 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}