Implement 'extern/url.php' as a regular route
authoreileen <emcnaughton@wikimedia.org>
Thu, 16 Apr 2020 04:06:51 +0000 (16:06 +1200)
committerTim Otten <totten@civicrm.org>
Wed, 13 May 2020 06:59:51 +0000 (23:59 -0700)
CRM/Mailing/Page/Url.php [new file with mode: 0644]
CRM/Mailing/xml/Menu/Mailing.xml
tests/phpunit/CRM/Mailing/BaseMailingSystemTest.php

diff --git a/CRM/Mailing/Page/Url.php b/CRM/Mailing/Page/Url.php
new file mode 100644 (file)
index 0000000..bd74484
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved.                        |
+ |                                                                    |
+ | This work is published under the GNU AGPLv3 license with some      |
+ | permitted exceptions and without any warranty. For full license    |
+ | and copyright information, see https://civicrm.org/licensing       |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC https://civicrm.org/licensing
+ */
+
+/**
+ * Redirects a user to the full url from a mailing url.
+ */
+class CRM_Mailing_Page_Url extends CRM_Core_Page {
+
+  /**
+   * Redirect the user to the specified url.
+   *
+   * @throws \CRM_Core_Exception
+   */
+  public function run() {
+    $queue_id = CRM_Utils_Request::retrieveValue('qid', 'Integer');
+    $url_id = CRM_Utils_Request::retrieveValue('u', 'Integer', NULL, TRUE);
+    $url = CRM_Mailing_Event_BAO_TrackableURLOpen::track($queue_id, $url_id);
+
+    // CRM-7103
+    // Looking for additional query variables and append them when redirecting.
+    $query_param = $_GET;
+    unset($query_param['qid'], $query_param['u']);
+    $query_string = http_build_query($query_param);
+
+    if (strlen($query_string) > 0) {
+      // Parse the url to preserve the fragment.
+      $pieces = parse_url($url);
+
+      if (isset($pieces['fragment'])) {
+        $url = str_replace('#' . $pieces['fragment'], '', $url);
+      }
+
+      // Handle additional query string params.
+      if ($query_string) {
+        if (stristr($url, '?')) {
+          $url .= '&' . $query_string;
+        }
+        else {
+          $url .= '?' . $query_string;
+        }
+      }
+
+      // slap the fragment onto the end per URL spec
+      if (isset($pieces['fragment'])) {
+        $url .= '#' . $pieces['fragment'];
+      }
+    }
+    CRM_Utils_System::redirect($url);
+  }
+
+}
index 2df7db36229d4bba63c22a379fe3c25088c20f2c..7fea1938a446d6f948fa9c193424c7faeb4877a3 100644 (file)
     <page_callback>CRM_Mailing_Page_AJAX::getContactMailings</page_callback>
     <access_arguments>access CiviCRM</access_arguments>
   </item>
+  <item>
+    <path>civicrm/mailing/url</path>
+    <page_callback>CRM_Mailing_Page_Url</page_callback>
+    <access_arguments>*always allow*</access_arguments>
+  </item>
 </menu>
index fa637eb0cdf32d821b0c77f7658814b92a67a321..c1a262b9ee9a265bd3ac5820c2b3d923b19d0f4f 100644 (file)
@@ -200,7 +200,7 @@ abstract class CRM_Mailing_BaseMailingSystemTest extends CiviUnitTestCase {
       $this->assertRegExp(
         ";" .
         // body_html
-        "<p>You can go to <a href=['\"].*extern/url\.php\?u=\d+&amp\\;qid=\d+['\"] rel='nofollow'>Google</a>" .
+        "<p>You can go to <a href=['\"].*civicrm/mailing/url\.php\?u=\d+&amp\\;qid=\d+['\"] rel='nofollow'>Google</a>" .
         " or <a href=\"http.*civicrm/mailing/optout.*\">opt out</a>.</p>\n" .
         // Default footer
         "Sample Footer for HTML formatted content" .
@@ -219,7 +219,7 @@ abstract class CRM_Mailing_BaseMailingSystemTest extends CiviUnitTestCase {
         "\n" .
         "Links:\n" .
         "------\n" .
-        "\\[1\\] .*extern/url\.php\?u=\d+&qid=\d+\n" .
+        "\\[1\\] http.*civicrm/mailing/url\.php\?u=\d+&qid=\d+\n" .
         "\\[2\\] http.*civicrm/mailing/optout.*\n" .
         "\n" .
         // Default footer
@@ -280,8 +280,8 @@ abstract class CRM_Mailing_BaseMailingSystemTest extends CiviUnitTestCase {
     // Tracking enabled
     $cases[] = [
       '<p><a href="http://example.net/">Foo</a></p>',
-      ';<p><a href=[\'"].*extern/url\.php\?u=\d+.*[\'"]>Foo</a></p>;',
-      ';\\[1\\] .*extern/url\.php\?u=\d+.*;',
+      ';<p><a href=[\'"].*civicrm/mailing/url\.php\?u=\d+.*[\'"]>Foo</a></p>;',
+      ';\\[1\\] .*civicrm/mailing/url\.php\?u=\d+.*;',
       ['url_tracking' => 1],
     ];
     $cases[] = [
@@ -311,7 +311,7 @@ abstract class CRM_Mailing_BaseMailingSystemTest extends CiviUnitTestCase {
       // but not in HTML emails.
       "<p>Please go to: http://example.net/</p>",
       ";<p>Please go to: http://example\.net/</p>;",
-      ';Please go to: .*extern/url.php\?u=\d+&qid=\d+;',
+      ';Please go to: .*civicrm/mailing.php\?u=\d+&qid=\d+;',
       ['url_tracking' => 1],
     ];
 
@@ -322,6 +322,7 @@ abstract class CRM_Mailing_BaseMailingSystemTest extends CiviUnitTestCase {
    * Generate a fully-formatted mailing (with body_html content).
    *
    * @dataProvider urlTrackingExamples
+   * @throws \CRM_Core_Exception
    */
   public function testUrlTracking($inputHtml, $htmlUrlRegex, $textUrlRegex, $params) {
     $caseName = print_r(['inputHtml' => $inputHtml, 'params' => $params], 1);