);
}
+ /**
+ * Alter redirect.
+ *
+ * This hook is called when the browser is being re-directed and allows the url
+ * to be altered.
+ *
+ * @param \Psr\Http\Message\UriInterface $url
+ * @param array $context
+ * Additional information about context
+ * - output - if this is 'json' then it will return json.
+ *
+ * @return null
+ * the return value is ignored
+ */
+ public static function alterRedirect($url, &$context) {
+ return self::singleton()->invoke(array('url', 'context'), $url,
+ $context, self::$_nullObject,
+ self::$_nullObject, self::$_nullObject, self::$_nullObject,
+ 'civicrm_alterRedirect'
+ );
+ }
+
/**
* @param $varType
* @param $var
*
* @param string $url
* The URL to provide to the browser via the Location header.
+ * @param array $context
+ * Optional additional information for the hook.
*/
- public static function redirect($url = NULL) {
+ public static function redirect($url = NULL, $context = []) {
if (!$url) {
$url = self::url('civicrm/dashboard', 'reset=1');
}
// this is kinda hackish but not sure how to do it right
$url = str_replace('&', '&', $url);
+ $context['output'] = CRM_Utils_Array::value('snippet', $_GET);
+
+ $parsedUrl = CRM_Utils_Url::parseUrl($url);
+ CRM_Utils_Hook::alterRedirect($parsedUrl, $context);
+ $url = CRM_Utils_Url::unparseUrl($parsedUrl);
+
// If we are in a json context, respond appropriately
- if (CRM_Utils_Array::value('snippet', $_GET) === 'json') {
+ if ($context['output'] === 'json') {
CRM_Core_Page_AJAX::returnJsonResponse(array(
'status' => 'redirect',
'userContext' => $url,
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.7 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2017 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License and the CiviCRM Licensing Exception along |
+ | with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+use GuzzleHttp\Psr7\Uri;
+use Psr\Http\Message\UriInterface;
+
+class CRM_Utils_Url {
+
+ /**
+ * Parse url to a UriInterface.
+ *
+ * @param string $url
+ *
+ * @return UriInterface
+ */
+ public static function parseUrl($url) {
+ return new Uri($url);
+ }
+
+ /**
+ * Unparse url back to a string.
+ *
+ * @param UriInterface $parsed
+ *
+ * @return string
+ */
+ public static function unparseUrl(UriInterface $parsed) {
+ return $parsed->__toString();
+ }
+
+}
"pear/Auth_SASL": "1.1.0",
"pear/Net_SMTP": "1.6.*",
"pear/Net_socket": "1.0.*",
- "civicrm/civicrm-setup": "~0.2.0"
+ "civicrm/civicrm-setup": "~0.2.0",
+ "guzzlehttp/guzzle": "^6.3"
},
"repositories": [
{
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "content-hash": "3bf4a12287208a8b232989680663e7a2",
+ "content-hash": "9c5441f5ce4c51ed3a8cc326693cd904",
"packages": [
{
"name": "civicrm/civicrm-cxn-rpc",
"homepage": "http://code.google.com/p/phpquery/",
"time": "2013-03-21T12:39:33+00:00"
},
+ {
+ "name": "guzzlehttp/guzzle",
+ "version": "6.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle.git",
+ "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699",
+ "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/promises": "^1.0",
+ "guzzlehttp/psr7": "^1.4",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "ext-curl": "*",
+ "phpunit/phpunit": "^4.0 || ^5.0",
+ "psr/log": "^1.0"
+ },
+ "suggest": {
+ "psr/log": "Required for using the Log middleware"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "6.2-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
+ "psr-4": {
+ "GuzzleHttp\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle is a PHP HTTP client library",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "rest",
+ "web service"
+ ],
+ "time": "2017-06-22T18:50:49+00:00"
+ },
+ {
+ "name": "guzzlehttp/promises",
+ "version": "v1.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/promises.git",
+ "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+ "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Promise\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle promises library",
+ "keywords": [
+ "promise"
+ ],
+ "time": "2016-12-20T10:07:11+00:00"
+ },
+ {
+ "name": "guzzlehttp/psr7",
+ "version": "1.4.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
+ "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "psr/http-message": "~1.0"
+ },
+ "provide": {
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Schultze",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": [
+ "http",
+ "message",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
+ ],
+ "time": "2017-03-20T17:10:46+00:00"
+ },
{
"name": "marcj/topsort",
"version": "1.1.0",
],
"time": "2017-06-05T06:30:30+00:00"
},
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "time": "2016-08-06T14:39:51+00:00"
+ },
{
"name": "psr/log",
"version": "1.0.0",
<?php
+use Psr\Http\Message\UriInterface;
+
/**
* Class CRM_Utils_SystemTest
* @group headless
$this->assertEquals('http://example.com/?cms=UnitTests', CRM_Utils_System::evalUrl('http://example.com/?cms={uf}'));
}
+ /**
+ * Test the redirect hook.
+ *
+ * @param string $url
+ * @param array $parsedUrl
+ *
+ * @dataProvider getURLs
+ */
+ public function testRedirectHook($url, $parsedUrl) {
+ $this->hookClass->setHook('civicrm_alterRedirect', array($this, 'hook_civicrm_alterRedirect'));
+ try {
+ CRM_Utils_System::redirect($url, [
+ 'expected' => $parsedUrl,
+ 'original' => $url
+ ]);
+ }
+ catch (CRM_Core_Exception $e) {
+ $this->assertEquals(ts('hook called'), $e->getMessage());
+ return;
+ }
+ $this->fail('Exception should have been thrown if hook was called');
+ }
+
+ /**
+ * Hook for alterRedirect.
+ *
+ * We do some checks here.
+ *
+ * @param UriInterface $urlQuery
+ * @param array $context
+ *
+ * @throws \CRM_Core_Exception
+ */
+ public function hook_civicrm_alterRedirect($urlQuery, $context) {
+ $this->assertEquals(CRM_Utils_Array::value('scheme', $context['expected']), $urlQuery->getScheme());
+ $this->assertEquals(CRM_Utils_Array::value('host', $context['expected']), $urlQuery->getHost());
+ $this->assertEquals(CRM_Utils_Array::value('query', $context['expected']), $urlQuery->getQuery());
+ $this->assertEquals($context['original'], CRM_Utils_Url::unparseUrl($urlQuery));
+
+ throw new CRM_Core_Exception(ts('hook called'));
+ }
+
+ /**
+ * Get urls for testing.
+ *
+ * @return array
+ */
+ public function getURLs() {
+ return [
+ ['https://example.com?ab=cd', [
+ 'scheme' => 'https',
+ 'host' => 'example.com',
+ 'query' => 'ab=cd',
+ ]],
+ ['http://myuser:mypass@foo.bar:123/whiz?a=b&c=d', [
+ 'scheme' => 'http',
+ 'host' => 'foo.bar',
+ 'port' => 123,
+ 'user' => 'myuser',
+ 'pass' => 'mypass',
+ 'path' => '/whiz',
+ 'query' => 'a=b&c=d',
+ ]],
+ ['/foo/bar', [
+ 'path' => '/foo/bar'
+ ]],
+ ];
+ }
+
}