Issue #2364157 by mpdonadio, dawehner, martin107, Berdir, pcambra, naveenvalecha, tim.plunkett: Replace most existing _url calls with Url objects

8.0.x
webchick 2015-01-29 20:56:19 -08:00
parent 0e914b24f6
commit 0fb9bb5474
78 changed files with 398 additions and 234 deletions

View File

@ -153,10 +153,12 @@ function _batch_progress_page() {
// Merge required query parameters for batch processing into those provided by
// batch_set() or hook_batch_alter().
$batch['url_options']['query']['id'] = $batch['id'];
$batch['url_options']['query']['op'] = $new_op;
$query_options = $batch['url']->getOption('query');
$query_options['id'] = $batch['id'];
$query_options['op'] = $new_op;
$batch['url']->setOption('query', $query_options);
$url = _url($batch['url'], $batch['url_options']);
$url = $batch['url']->toString();
$build = array(
'#theme' => 'progress_bar',

View File

@ -745,9 +745,10 @@ function batch_set($batch_definition) {
* This function is generally not needed in form submit handlers;
* Form API takes care of batches that were set during form submission.
*
* @param $redirect
* (optional) Path to redirect to when the batch has finished processing.
* @param $url
* @param \Drupal\Core\Url|string $redirect
* (optional) Either path or Url object to redirect to when the batch has
* finished processing.
* @param \Drupal\Core\Url $url
* (optional - should only be used for separate scripts like update.php)
* URL of the batch processing page.
* @param $redirect_callback
@ -757,7 +758,7 @@ function batch_set($batch_definition) {
* @return \Symfony\Component\HttpFoundation\RedirectResponse|null
* A redirect response if the batch is progressive. No return value otherwise.
*/
function batch_process($redirect = NULL, $url = 'batch', $redirect_callback = NULL) {
function batch_process($redirect = NULL, Url $url = NULL, $redirect_callback = NULL) {
$batch =& batch_get();
if (isset($batch)) {
@ -765,8 +766,7 @@ function batch_process($redirect = NULL, $url = 'batch', $redirect_callback = NU
$process_info = array(
'current_set' => 0,
'progressive' => TRUE,
'url' => $url,
'url_options' => array(),
'url' => isset($url) ? $url : Url::fromRoute('system.batch_page.html'),
'source_url' => Url::fromRouteMatch(\Drupal::routeMatch()),
'batch_redirect' => $redirect,
'theme' => \Drupal::theme()->getActiveTheme()->getName(),
@ -793,7 +793,16 @@ function batch_process($redirect = NULL, $url = 'batch', $redirect_callback = NU
if ($batch['progressive']) {
// Now that we have a batch id, we can generate the redirection link in
// the generic error message.
$batch['error_message'] = t('Please continue to <a href="@error_url">the error page</a>', array('@error_url' => _url($url, array('query' => array('id' => $batch['id'], 'op' => 'finished')))));
/** @var \Drupal\Core\Url $batch_url */
$batch_url = $batch['url'];
/** @var \Drupal\Core\Url $error_url */
$error_url = clone $batch_url;
$query_options = $error_url->getOption('query');
$query_options['id'] = $batch['id'];
$query_options['op'] = 'finished';
$error_url->setOption('query', $query_options);
$batch['error_message'] = t('Please continue to <a href="@error_url">the error page</a>', array('@error_url' => $error_url->toString()));
// Clear the way for the redirection to the batch processing page, by
// saving and unsetting the 'destination', if there is any.
@ -815,13 +824,15 @@ function batch_process($redirect = NULL, $url = 'batch', $redirect_callback = NU
$_SESSION['batches'][$batch['id']] = TRUE;
// Redirect for processing.
$options = array('query' => array('op' => 'start', 'id' => $batch['id']));
$query_options = $error_url->getOption('query');
$query_options['op'] = 'start';
$query_options['id'] = $batch['id'];
$batch_url->setOption('query', $query_options);
if (($function = $batch['redirect_callback']) && function_exists($function)) {
$function($batch['url'], $options);
$function($batch_url->toString(), ['query' => $query_options]);
}
else {
$options['absolute'] = TRUE;
return new RedirectResponse(_url($batch['url'], $options));
return new RedirectResponse($batch_url->setAbsolute()->toString());
}
}
else {

View File

@ -18,6 +18,7 @@ use Drupal\Core\Site\Settings;
use Drupal\Core\StringTranslation\Translator\FileTranslation;
use Drupal\Core\Extension\ExtensionDiscovery;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Url;
use Drupal\language\Entity\ConfigurableLanguage;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpFoundation\Request;
@ -581,10 +582,10 @@ function install_run_task($task, &$install_state) {
}
// Process the batch. For progressive batches, this will redirect.
// Otherwise, the batch will complete.
// install_redirect_url() returns core/install.php, so let's ensure to
// drop it from it and use base:// as batch_process() is using the
// unrouted URL assembler, which requires base://.
$response = batch_process(preg_replace('@^core/@', 'base://', install_redirect_url($install_state)), install_full_redirect_url($install_state));
// Disable the default script for the URL and clone the object, as
// batch_process() will add additional options to the batch URL.
$url = Url::fromUri('base://install.php', ['query' => $install_state['parameters'], 'script' => '']);
$response = batch_process($url, clone $url);
if ($response instanceof Response) {
// Save $_SESSION data from batch.
\Drupal::service('session_manager')->save();

View File

@ -134,7 +134,6 @@ class UrlHelper {
* - fragment: The fragment component from $url, if it exists.
*
* @see \Drupal\Core\Utility\LinkGenerator
* @see _url()
* @see http://tools.ietf.org/html/rfc3986
*
* @ingroup php_wrappers

View File

@ -28,7 +28,7 @@ class RedirectCommand implements CommandInterface {
*
* @param string $url
* The URL that will be loaded into window.location. This should be a full
* URL, one that has already been run through the _url() function.
* URL.
*/
public function __construct($url) {
$this->url = $url;

View File

@ -119,7 +119,7 @@ class CssOptimizer implements AssetOptimizerInterface {
* Loads stylesheets recursively and returns contents with corrected paths.
*
* This function is used for recursive loading of stylesheets and
* returns the stylesheet content with all _url() paths corrected.
* returns the stylesheet content with all url() paths corrected.
*
* @param array $matches
* An array of matches by a preg_replace_callback() call that scans for
@ -138,10 +138,10 @@ class CssOptimizer implements AssetOptimizerInterface {
// Determine the file's directory.
$directory = dirname($filename);
// If the file is in the current directory, make sure '.' doesn't appear in
// the _url() path.
// the url() path.
$directory = $directory == '.' ? '' : $directory .'/';
// Alter all internal _url() paths. Leave external paths alone. We don't need
// Alter all internal url() paths. Leave external paths alone. We don't need
// to normalize absolute paths here (i.e. remove folder/... segments)
// because that will be done later.
return preg_replace('/url\(\s*([\'"]?)(?![a-z]+:|\/+)([^\'")]+)([\'"]?)\s*\)/i', 'url(\1' . $directory . '\2\3)', $file);
@ -215,7 +215,7 @@ class CssOptimizer implements AssetOptimizerInterface {
*
* @param array $matches
* An array of matches by a preg_replace_callback() call that scans for
* _url() references in CSS files, except for external or absolute ones.
* url() references in CSS files, except for external or absolute ones.
*
* Note: the only reason this method is public is so color.module can call it;
* it is not on the AssetOptimizerInterface, so future refactorings can make

View File

@ -193,8 +193,8 @@ abstract class Entity implements EntityInterface {
}
}
// Pass the entity data to _url() so that alter functions do not need to
// look up this entity again.
// Pass the entity data through as options, so that alter functions do not
// need to look up this entity again.
$uri
->setOption('entity_type', $this->getEntityTypeId())
->setOption('entity', $this);

View File

@ -1273,7 +1273,7 @@ class MenuTreeStorage implements MenuTreeStorageInterface {
'not null' => FALSE,
),
'options' => array(
'description' => 'A serialized array of options to be passed to the _url() or _l() function, such as a query string or HTML attributes.',
'description' => 'A serialized array of URL options, such as a query string or HTML attributes.',
'type' => 'blob',
'size' => 'big',
'not null' => FALSE,

View File

@ -88,7 +88,7 @@ class AliasWhitelist extends CacheCollector implements AliasWhitelistInterface {
*/
public function get($offset) {
$this->lazyLoadCache();
// _url() may be called with paths that are not represented by menu router
// this may be called with paths that are not represented by menu router
// items such as paths that will be rewritten by hook_url_outbound_alter().
// Therefore internally TRUE is used to indicate whitelisted paths. FALSE is
// used to indicate paths that have already been checked but are not

View File

@ -291,9 +291,8 @@ abstract class RenderElement extends PluginBase implements ElementInterface {
$settings['progress'] = array('type' => $settings['progress']);
}
// Change progress path to a full URL.
if (isset($settings['progress']['path'])) {
$settings['progress']['url'] = _url($settings['progress']['path']);
unset($settings['progress']['path']);
if (isset($settings['progress']['url']) && $settings['progress']['url'] instanceof Url) {
$settings['progress']['url'] = $settings['progress']['url']->toString();
}
$element['#attached']['drupalSettings']['ajax'][$element['#id']] = $settings;

View File

@ -251,8 +251,7 @@ class UrlGenerator extends ProviderBasedGenerator implements UrlGeneratorInterfa
// \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols() if $path
// contains a ':' before any / ? or #. Note: we could use
// \Drupal\Component\Utility\UrlHelper::isExternal($path) here, but that
// would require another function call, and performance inside _url() is
// critical.
// would require another function call, and performance here is critical.
$colonpos = strpos($path, ':');
$options['external'] = ($colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && UrlHelper::stripDangerousProtocols($path) == $path);
}

View File

@ -155,13 +155,29 @@ class UnroutedUrlAssembler implements UnroutedUrlAssemblerInterface {
* The options to merge in the defaults.
*/
protected function addOptionDefaults(array &$options) {
$request = $this->requestStack->getCurrentRequest();
$current_base_path = $request->getBasePath() . '/';
$current_script_path = '';
$base_path_with_script = $request->getBaseUrl();
// If the current request was made with the script name (eg, index.php) in
// it, then extract it, making sure the leading / is gone, and a trailing /
// is added, to allow simple string concatenation with other parts. This
// mirrors code from UrlGenerator::generateFromPath().
if (!empty($base_path_with_script)) {
$script_name = $request->getScriptName();
if (strpos($base_path_with_script, $script_name) !== FALSE) {
$current_script_path = ltrim(substr($script_name, strlen($current_base_path)), '/') . '/';
}
}
// Merge in defaults.
$options += [
'fragment' => '',
'query' => [],
'absolute' => FALSE,
'prefix' => '',
'script' => '',
'script' => $current_script_path,
];
if (isset($options['fragment']) && $options['fragment'] !== '') {

View File

@ -7,6 +7,7 @@
namespace Drupal\aggregator\Tests;
use Drupal\Core\Url;
use Zend\Feed\Reader\Reader;
/**
@ -76,12 +77,11 @@ class FeedParserTest extends AggregatorTestBase {
}
/**
* Tests error handling when an invalid feed is added.
* Tests that a redirected feed is tracked to its target.
*/
function testRedirectFeed() {
// Simulate a typo in the URL to force a curl exception.
$invalid_url = _url('aggregator/redirect', array('absolute' => TRUE));
$feed = entity_create('aggregator_feed', array('url' => $invalid_url, 'title' => $this->randomMachineName()));
$redirect_url = Url::fromRoute('aggregator_test.redirect')->setAbsolute()->toString();
$feed = entity_create('aggregator_feed', array('url' => $redirect_url, 'title' => $this->randomMachineName()));
$feed->save();
$feed->refreshItems();

View File

@ -7,6 +7,7 @@
namespace Drupal\basic_auth\Tests\Authentication;
use Drupal\Core\Url;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\simpletest\WebTestBase;
@ -29,18 +30,21 @@ class BasicAuthTest extends WebTestBase {
*/
public function testBasicAuth() {
$account = $this->drupalCreateUser();
$url = Url::fromRoute('router_test.11');
$this->basicAuthGet('router_test/test11', $account->getUsername(), $account->pass_raw);
$this->basicAuthGet($url, $account->getUsername(), $account->pass_raw);
$this->assertText($account->getUsername(), 'Account name is displayed.');
$this->assertResponse('200', 'HTTP response is OK');
$this->curlClose();
$this->basicAuthGet('router_test/test11', $account->getUsername(), $this->randomMachineName());
$this->basicAuthGet($url, $account->getUsername(), $this->randomMachineName());
$this->assertNoText($account->getUsername(), 'Bad basic auth credentials do not authenticate the user.');
$this->assertResponse('403', 'Access is not granted.');
$this->curlClose();
$this->drupalGet('router_test/test11');
// @todo Change ->drupalGet() calls to just pass $url when
// https://www.drupal.org/node/2350837 gets committed
$this->drupalGet($url->setAbsolute()->toString());
$this->assertResponse('401', 'Not authenticated on the route that allows only basic_auth. Prompt to authenticate received.');
$this->drupalGet('admin');
@ -48,7 +52,7 @@ class BasicAuthTest extends WebTestBase {
$account = $this->drupalCreateUser(array('access administration pages'));
$this->basicAuthGet('admin', $account->getUsername(), $account->pass_raw);
$this->basicAuthGet(Url::fromRoute('system.admin'), $account->getUsername(), $account->pass_raw);
$this->assertNoLink('Log out', 0, 'User is not logged in');
$this->assertResponse('403', 'No basic authentication for routes not explicitly defining authentication providers.');
$this->curlClose();
@ -67,14 +71,15 @@ class BasicAuthTest extends WebTestBase {
$user = $this->drupalCreateUser(array());
$incorrect_user = clone $user;
$incorrect_user->pass_raw .= 'incorrect';
$url = Url::fromRoute('router_test.11');
// Try 2 failed logins.
for ($i = 0; $i < 2; $i++) {
$this->basicAuthGet('router_test/test11', $incorrect_user->getUsername(), $incorrect_user->pass_raw);
$this->basicAuthGet($url, $incorrect_user->getUsername(), $incorrect_user->pass_raw);
}
// IP limit has reached to its limit. Even valid user credentials will fail.
$this->basicAuthGet('router_test/test11', $user->getUsername(), $user->pass_raw);
$this->basicAuthGet($url, $user->getUsername(), $user->pass_raw);
$this->assertResponse('403', 'Access is blocked because of IP based flood prevention.');
}
@ -92,26 +97,27 @@ class BasicAuthTest extends WebTestBase {
$incorrect_user = clone $user;
$incorrect_user->pass_raw .= 'incorrect';
$user2 = $this->drupalCreateUser(array());
$url = Url::fromRoute('router_test.11');
// Try a failed login.
$this->basicAuthGet('router_test/test11', $incorrect_user->getUsername(), $incorrect_user->pass_raw);
$this->basicAuthGet($url, $incorrect_user->getUsername(), $incorrect_user->pass_raw);
// A successful login will reset the per-user flood control count.
$this->basicAuthGet('router_test/test11', $user->getUsername(), $user->pass_raw);
$this->basicAuthGet($url, $user->getUsername(), $user->pass_raw);
$this->assertResponse('200', 'Per user flood prevention gets reset on a successful login.');
// Try 2 failed logins for a user. They will trigger flood control.
for ($i = 0; $i < 2; $i++) {
$this->basicAuthGet('router_test/test11', $incorrect_user->getUsername(), $incorrect_user->pass_raw);
$this->basicAuthGet($url, $incorrect_user->getUsername(), $incorrect_user->pass_raw);
}
// Now the user account is blocked.
$this->basicAuthGet('router_test/test11', $user->getUsername(), $user->pass_raw);
$this->basicAuthGet($url, $user->getUsername(), $user->pass_raw);
$this->assertResponse('403', 'The user account is blocked due to per user flood prevention.');
// Try one successful attempt for a different user, it should not trigger
// any flood control.
$this->basicAuthGet('router_test/test11', $user2->getUsername(), $user2->pass_raw);
$this->basicAuthGet($url, $user2->getUsername(), $user2->pass_raw);
$this->assertResponse('200', 'Per user flood prevention does not block access for other users.');
}
@ -123,8 +129,9 @@ class BasicAuthTest extends WebTestBase {
$this->config('system.site')->set('langcode', 'de')->save();
$account = $this->drupalCreateUser();
$url = Url::fromRoute('router_test.11');
$this->basicAuthGet('router_test/test11', $account->getUsername(), $account->pass_raw);
$this->basicAuthGet($url, $account->getUsername(), $account->pass_raw);
$this->assertText($account->getUsername(), 'Account name is displayed.');
$this->assertResponse('200', 'HTTP response is OK');
$this->curlClose();
@ -136,8 +143,8 @@ class BasicAuthTest extends WebTestBase {
* We do not use \Drupal\simpletest\WebTestBase::drupalGet because we need to
* set curl settings for basic authentication.
*
* @param string $path
* The request path.
* @param \Drupal\Core\Url|string $path
* Drupal path or URL to load into internal browser
* @param string $username
* The user name to authenticate with.
* @param string $password
@ -147,10 +154,14 @@ class BasicAuthTest extends WebTestBase {
* Curl output.
*/
protected function basicAuthGet($path, $username, $password) {
if ($path instanceof Url) {
$path = $path->setAbsolute()->toString();
}
$out = $this->curlExec(
array(
CURLOPT_HTTPGET => TRUE,
CURLOPT_URL => _url($path, array('absolute' => TRUE)),
CURLOPT_URL => $path,
CURLOPT_NOBODY => FALSE,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_USERPWD => $username . ':' . $password,

View File

@ -112,9 +112,9 @@ class DownloadTest extends FileManagedTestBase {
'%C3%A9%C3%B8%C3%AF%D0%B2%CE%B2%E4%B8%AD%E5%9C%8B%E6%9B%B8%DB%9E';
// Public files should not be served by Drupal, so their URLs should not be
// generated by _url(), whereas private files should be served by Drupal, so
// their URLs should be generated by _url(). The difference is most apparent
// when $script_path is not empty (i.e., when not using clean URLs).
// routed through Drupal, whereas private files should be served by Drupal,
// so they need to be. The difference is most apparent when $script_path
// is not empty (i.e., when not using clean URLs).
$clean_url_settings = array(
'clean' => '',
'unclean' => 'index.php/',

View File

@ -21,7 +21,7 @@ class FilterDefaultConfigTest extends KernelTestBase {
protected function setUp() {
parent::setUp();
// Drupal\filter\FilterPermissions::permissions() calls into _url() to output
// Drupal\filter\FilterPermissions::permissions() builds an URL to output
// a link in the description.
$this->installSchema('system', 'url_alias');

View File

@ -7,6 +7,7 @@
namespace Drupal\hal\Tests;
use Drupal\Core\Url;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
/**
@ -24,7 +25,7 @@ class DenormalizeTest extends NormalizerTestBase {
$data_with_valid_type = array(
'_links' => array(
'type' => array(
'href' => _url('rest/type/entity_test/entity_test', array('absolute' => TRUE)),
'href' => Url::fromUri('base://rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
),
),
);
@ -36,10 +37,10 @@ class DenormalizeTest extends NormalizerTestBase {
'_links' => array(
'type' => array(
array(
'href' => _url('rest/types/foo', array('absolute' => TRUE)),
'href' => Url::fromUri('base://rest/types/foo', array('absolute' => TRUE))->toString(),
),
array(
'href' => _url('rest/type/entity_test/entity_test', array('absolute' => TRUE)),
'href' => Url::fromUri('base://rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
),
),
),
@ -51,7 +52,7 @@ class DenormalizeTest extends NormalizerTestBase {
$data_with_invalid_type = array(
'_links' => array(
'type' => array(
'href' => _url('rest/types/foo', array('absolute' => TRUE)),
'href' => Url::fromUri('base://rest/types/foo', array('absolute' => TRUE))->toString(),
),
),
);
@ -84,7 +85,7 @@ class DenormalizeTest extends NormalizerTestBase {
$no_field_data = array(
'_links' => array(
'type' => array(
'href' => _url('rest/type/entity_test/entity_test', array('absolute' => TRUE)),
'href' => Url::fromUri('base://rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
),
),
);
@ -94,7 +95,7 @@ class DenormalizeTest extends NormalizerTestBase {
$empty_field_data = array(
'_links' => array(
'type' => array(
'href' => _url('rest/type/entity_test/entity_test', array('absolute' => TRUE)),
'href' => Url::fromUri('base://rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
),
),
'field_test_text' => array(),
@ -112,7 +113,7 @@ class DenormalizeTest extends NormalizerTestBase {
$data = array(
'_links' => array(
'type' => array(
'href' => _url('rest/type/entity_test/entity_test', array('absolute' => TRUE)),
'href' => Url::fromUri('base://rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
),
),
'uuid' => array(
@ -182,7 +183,7 @@ class DenormalizeTest extends NormalizerTestBase {
$data = array(
'_links' => array(
'type' => array(
'href' => _url('rest/type/entity_test/entity_test', array('absolute' => TRUE)),
'href' => Url::fromUri('base://rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
),
),
'field_test_text' => array(

View File

@ -39,7 +39,8 @@ class FileNormalizeTest extends NormalizerTestBase {
$this->installEntitySchema('file');
$entity_manager = \Drupal::entityManager();
$link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default')), new RelationLinkManager(new MemoryBackend('default'), $entity_manager));
$url_assembler = \Drupal::service('unrouted_url_assembler');
$link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default'), $url_assembler), new RelationLinkManager(new MemoryBackend('default'), $entity_manager, $url_assembler));
// Set up the mock serializer.
$normalizers = array(

View File

@ -7,6 +7,8 @@
namespace Drupal\hal\Tests;
use Drupal\Core\Url;
/**
* Tests that entities can be normalized in HAL.
*
@ -59,8 +61,8 @@ class NormalizeTest extends NormalizerTestBase {
$entity->getTranslation('en')->set('field_test_entity_reference', array(0 => $translation_values['field_test_entity_reference']));
$entity->save();
$type_uri = _url('rest/type/entity_test/entity_test', array('absolute' => TRUE));
$relation_uri = _url('rest/relation/entity_test/entity_test/field_test_entity_reference', array('absolute' => TRUE));
$type_uri = Url::fromUri('base://rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString();
$relation_uri = Url::fromUri('base://rest/relation/entity_test/entity_test/field_test_entity_reference', array('absolute' => TRUE))->toString();
$expected_array = array(
'_links' => array(

View File

@ -134,7 +134,8 @@ abstract class NormalizerTestBase extends KernelTestBase {
))->save();
$entity_manager = \Drupal::entityManager();
$link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default')), new RelationLinkManager(new MemoryBackend('default'), $entity_manager));
$url_assembler = \Drupal::service('unrouted_url_assembler');
$link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default'), $url_assembler), new RelationLinkManager(new MemoryBackend('default'), $entity_manager, $url_assembler));
$chain_resolver = new ChainEntityResolver(array(new UuidResolver($entity_manager), new TargetIdResolver()));

View File

@ -14,6 +14,7 @@ use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
use Drupal\Core\Routing\RequestHelper;
use Drupal\Core\Site\Settings;
use Drupal\Core\Url;
use Drupal\image\ImageEffectPluginCollection;
use Drupal\image\ImageEffectInterface;
use Drupal\image\ImageStyleInterface;
@ -218,12 +219,13 @@ class ImageStyle extends ConfigEntityBase implements ImageStyleInterface, Entity
}
// If not using clean URLs, the image derivative callback is only available
// with the script path. If the file does not exist, use _url() to ensure
// that it is included. Once the file exists it's fine to fall back to the
// actual file path, this avoids bootstrapping PHP once the files are built.
// with the script path. If the file does not exist, use Url::fromUri() to
// ensure that it is included. Once the file exists it's fine to fall back
// to the actual file path, this avoids bootstrapping PHP once the files are
// built.
if ($clean_urls === FALSE && file_uri_scheme($uri) == 'public' && !file_exists($uri)) {
$directory_path = file_stream_wrapper_get_instance_by_uri($uri)->getDirectoryPath();
return _url($directory_path . '/' . file_uri_target($uri), array('absolute' => TRUE, 'query' => $token_query));
return Url::fromUri('base://' . $directory_path . '/' . file_uri_target($uri), array('absolute' => TRUE, 'query' => $token_query))->toString();
}
$file_url = file_create_url($uri);

View File

@ -25,7 +25,7 @@ use Drupal\Core\Session\AccountInterface;
* - Content language: The language used to present content that is available
* in more than one language.
* - URL language: The language associated with URLs. When generating a URL,
* this value will be used by _url() as a default if no explicit preference is
* this value will be used for URL's as a default if no explicit preference is
* provided.
* Modules can define additional language types through
* hook_language_types_info(), and alter existing language type definitions

View File

@ -7,6 +7,7 @@
namespace Drupal\language\Tests;
use Drupal\Core\Url;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationBrowser;
use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationSelected;
@ -417,7 +418,7 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
}
/**
* Tests _url() when separate domains are used for multiple languages.
* Tests URL handling when separate domains are used for multiple languages.
*/
function testLanguageDomain() {
global $base_url;
@ -462,23 +463,22 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
// Test URL in another language: http://it.example.com/admin.
// Base path gives problems on the testbot, so $correct_link is hard-coded.
// @see UrlAlterFunctionalTest::assertUrlOutboundAlter (path.test).
$italian_url = _url('admin', array('language' => $languages['it'], 'script' => ''));
$italian_url = Url::fromRoute('system.admin', [], ['language' => $languages['it']])->toString();
$url_scheme = \Drupal::request()->isSecure() ? 'https://' : 'http://';
$correct_link = $url_scheme . $link;
$this->assertEqual($italian_url, $correct_link, format_string('The _url() function returns the right URL (@url) in accordance with the chosen language', array('@url' => $italian_url)));
$this->assertEqual($italian_url, $correct_link, format_string('The right URL (@url) in accordance with the chosen language', array('@url' => $italian_url)));
// Test HTTPS via options.
$italian_url = _url('admin', array('https' => TRUE, 'language' => $languages['it'], 'script' => ''));
$italian_url = Url::fromRoute('system.admin', [], ['https' => TRUE, 'language' => $languages['it']])->toString();
$correct_link = 'https://' . $link;
$this->assertTrue($italian_url == $correct_link, format_string('The _url() function returns the right HTTPS URL (via options) (@url) in accordance with the chosen language', array('@url' => $italian_url)));
$this->assertTrue($italian_url == $correct_link, format_string('The right HTTPS URL (via options) (@url) in accordance with the chosen language', array('@url' => $italian_url)));
// Test HTTPS via current URL scheme.
$request = Request::create('', 'GET', array(), array(), array(), array('HTTPS' => 'on'));
$this->container->get('request_stack')->push($request);
$generator = $this->container->get('url_generator');
$italian_url = _url('admin', array('language' => $languages['it'], 'script' => ''));
$italian_url = Url::fromRoute('system.admin', [], ['language' => $languages['it']])->toString();
$correct_link = 'https://' . $link;
$this->assertTrue($italian_url == $correct_link, format_string('The _url() function returns the right URL (via current URL scheme) (@url) in accordance with the chosen language', array('@url' => $italian_url)));
$this->assertTrue($italian_url == $correct_link, format_string('The right URL (via current URL scheme) (@url) in accordance with the chosen language', array('@url' => $italian_url)));
}
/**

View File

@ -9,6 +9,7 @@ namespace Drupal\language\Tests;
use Drupal\Core\Language\Language;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Url;
use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
use Drupal\simpletest\WebTestBase;
use Symfony\Component\HttpFoundation\Request;
@ -138,21 +139,21 @@ class LanguageUrlRewritingTest extends WebTestBase {
// Create an absolute French link.
$language = \Drupal::languageManager()->getLanguage('fr');
$url = _url('', array(
$url = Url::fromRoute('<none>', [], [
'absolute' => TRUE,
'language' => $language,
));
])->toString();
$expected = ($index_php ? 'http://example.fr:88/index.php' : 'http://example.fr:88') . rtrim(base_path(), '/') . '/';
$this->assertEqual($url, $expected, 'The right port is used.');
// If we set the port explicitly in _url(), it should not be overriden.
$url = _url('', array(
// If we set the port explicitly, it should not be overriden.
$url = Url::fromRoute('<none>', [], [
'absolute' => TRUE,
'language' => $language,
'base_url' => $request->getBaseUrl() . ':90',
));
])->toString();
$expected = $index_php ? 'http://example.fr:90/index.php' : 'http://example.fr:90' . rtrim(base_path(), '/') . '/';

View File

@ -8,6 +8,7 @@
namespace Drupal\locale\Tests;
use Drupal\Core\StreamWrapper\PublicStream;
use Drupal\Core\Url;
use Drupal\simpletest\WebTestBase;
use Drupal\Component\Utility\String;
@ -60,7 +61,7 @@ abstract class LocaleUpdateBase extends WebTestBase {
// Update module should not go out to d.o to check for updates. We override
// the url to the default update_test xml path. But without providing
// a mock xml file, no update data will be found.
$this->config('update.settings')->set('fetch.url', _url('update-test', array('absolute' => TRUE)))->save();
$this->config('update.settings')->set('fetch.url', Url::fromRoute('update_test.update_test', [], ['absolute' => TRUE])->toString())->save();
// Setup timestamps to identify old and new translation sources.
$this->timestampOld = REQUEST_TIME - 300;

View File

@ -342,7 +342,7 @@ class MenuLinkContent extends ContentEntityBase implements MenuLinkContentInterf
$fields['options'] = BaseFieldDefinition::create('map')
->setLabel(t('Options'))
->setDescription(t('A serialized array of options to be passed to the _url() or _l() function, such as a query string or HTML attributes.'))
->setDescription(t('A serialized array of URL options, such as a query string or HTML attributes.'))
->setSetting('default_value', array());
$fields['external'] = BaseFieldDefinition::create('boolean')

View File

@ -119,11 +119,11 @@ class PathLanguageTest extends PathTestBase {
$this->drupalGet('fr/' . $edit['path[0][alias]']);
$this->assertText($french_node->body->value, 'Alias for French translation works.');
// Confirm that the alias is returned by _url(). Languages are cached on
// Confirm that the alias is returned for the URL. Languages are cached on
// many levels, and we need to clear those caches.
$this->container->get('language_manager')->reset();
$languages = $this->container->get('language_manager')->getLanguages();
$url = $this->container->get('url_generator')->generateFromPath('node/' . $french_node->id(), array('language' => $languages['fr']));
$url = $french_node->url('canonical', array('language' => $languages['fr']));
$this->assertTrue(strpos($url, $edit['path[0][alias]']), 'URL contains the path alias.');

View File

@ -18,10 +18,10 @@ services:
arguments: ['@rest.link_manager.type', '@rest.link_manager.relation']
rest.link_manager.type:
class: Drupal\rest\LinkManager\TypeLinkManager
arguments: ['@cache.default']
arguments: ['@cache.default', '@unrouted_url_assembler']
rest.link_manager.relation:
class: Drupal\rest\LinkManager\RelationLinkManager
arguments: ['@cache.default', '@entity.manager']
arguments: ['@cache.default', '@entity.manager', '@unrouted_url_assembler']
rest.resource_routes:
class: Drupal\rest\Routing\ResourceRoutes
arguments: ['@plugin.manager.rest', '@config.factory', '@logger.channel.rest']

View File

@ -11,6 +11,7 @@ use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Utility\UnroutedUrlAssemblerInterface;
class RelationLinkManager implements RelationLinkManagerInterface {
@ -26,6 +27,13 @@ class RelationLinkManager implements RelationLinkManagerInterface {
*/
protected $entityManager;
/**
* The unrouted URL assembler.
*
* @var \Drupal\Core\Utility\UnroutedUrlAssemblerInterface
*/
protected $urlAssembler;
/**
* Constructor.
*
@ -33,18 +41,20 @@ class RelationLinkManager implements RelationLinkManagerInterface {
* The cache of relation URIs and their associated Typed Data IDs.
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
* @param \Drupal\Core\Utility\UnroutedUrlAssemblerInterface $url_assembler
* The unrouted URL assembler.
*/
public function __construct(CacheBackendInterface $cache, EntityManagerInterface $entity_manager) {
public function __construct(CacheBackendInterface $cache, EntityManagerInterface $entity_manager, UnroutedUrlAssemblerInterface $url_assembler) {
$this->cache = $cache;
$this->entityManager = $entity_manager;
$this->urlAssembler = $url_assembler;
}
/**
* {@inheritdoc}
*/
public function getRelationUri($entity_type, $bundle, $field_name) {
// @todo Make the base path configurable.
return _url("rest/relation/$entity_type/$bundle/$field_name", array('absolute' => TRUE));
return $this->urlAssembler->assemble("base://rest/relation/$entity_type/$bundle/$field_name", array('absolute' => TRUE));
}
/**

View File

@ -9,6 +9,7 @@ namespace Drupal\rest\LinkManager;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Utility\UnroutedUrlAssemblerInterface;
class TypeLinkManager implements TypeLinkManagerInterface {
@ -19,14 +20,24 @@ class TypeLinkManager implements TypeLinkManagerInterface {
*/
protected $cache;
/**
* The unrouted URL assembler.
*
* @var \Drupal\Core\Utility\UnroutedUrlAssemblerInterface
*/
protected $urlAssembler;
/**
* Constructor.
*
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The injected cache backend for caching type URIs.
* @param \Drupal\Core\Utility\UnroutedUrlAssemblerInterface $url_assembler
* The unrouted URL assembler.
*/
public function __construct(CacheBackendInterface $cache) {
public function __construct(CacheBackendInterface $cache, UnroutedUrlAssemblerInterface $url_assembler) {
$this->cache = $cache;
$this->urlAssembler = $url_assembler;
}
/**
@ -42,7 +53,7 @@ class TypeLinkManager implements TypeLinkManagerInterface {
*/
public function getTypeUri($entity_type, $bundle) {
// @todo Make the base path configurable.
return _url("rest/type/$entity_type/$bundle", array('absolute' => TRUE));
return $this->urlAssembler->assemble("base://rest/type/$entity_type/$bundle", array('absolute' => TRUE));
}
/**

View File

@ -99,9 +99,8 @@ class EntityResource extends ResourceBase {
$entity->save();
$this->logger->notice('Created entity %type with ID %id.', array('%type' => $entity->getEntityTypeId(), '%id' => $entity->id()));
$url = _url(strtr($this->pluginId, ':', '/') . '/' . $entity->id(), array('absolute' => TRUE));
// 201 Created responses have an empty body.
return new ResourceResponse(NULL, 201, array('Location' => $url));
return new ResourceResponse(NULL, 201, array('Location' => $entity->url('canonical', ['absolute' => TRUE])));
}
catch (EntityStorageException $e) {
throw new HttpException(500, 'Internal Server Error', $e);

View File

@ -5,6 +5,8 @@
namespace Drupal\rest\Tests;
use Drupal\Core\Url;
/**
* Tests the CSRF protection.
*
@ -107,7 +109,7 @@ class CsrfTest extends RESTTestBase {
CURLOPT_HTTPGET => FALSE,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $this->serialized,
CURLOPT_URL => _url('entity/' . $this->testEntityType, array('absolute' => TRUE)),
CURLOPT_URL => Url::fromRoute('rest.entity.' . $this->testEntityType . '.POST')->setAbsolute()->toString(),
CURLOPT_NOBODY => FALSE,
CURLOPT_HTTPHEADER => array(
"Content-Type: {$this->defaultMimeType}",

View File

@ -7,6 +7,7 @@
namespace Drupal\rest\Tests;
use Drupal\Core\Url;
use Drupal\rest\Tests\RESTTestBase;
/**
@ -53,7 +54,7 @@ class DeleteTest extends RESTTestBase {
$this->assertEqual($response, '', 'Response body is empty.');
// Try to delete an entity that does not exist.
$response = $this->httpRequest($entity_type . '/9999', 'DELETE');
$response = $this->httpRequest(Url::fromRoute('entity.' . $entity_type . '.canonical', [$entity_type => 9999]), 'DELETE');
$this->assertResponse(404);
$this->assertText('The requested page could not be found.');
@ -70,9 +71,9 @@ class DeleteTest extends RESTTestBase {
$this->enableService(FALSE);
$account = $this->drupalCreateUser();
$this->drupalLogin($account);
$this->httpRequest('entity/user/' . $account->id(), 'DELETE');
$this->httpRequest($account->urlInfo(), 'DELETE');
$user = entity_load('user', $account->id(), TRUE);
$this->assertEqual($account->id(), $user->id(), 'User still exists in the database.');
$this->assertResponse(404);
$this->assertResponse(405);
}
}

View File

@ -7,6 +7,7 @@
namespace Drupal\rest\Tests;
use Drupal\Core\Url;
use Drupal\rest\Tests\RESTTestBase;
/**
@ -50,14 +51,14 @@ class NodeTest extends RESTTestBase {
$node = $this->entityCreate('node');
$node->save();
$this->httpRequest('node/' . $node->id(), 'GET', NULL, $this->defaultMimeType);
$this->httpRequest($node->urlInfo(), 'GET', NULL, $this->defaultMimeType);
$this->assertResponse(200);
$this->assertHeader('Content-type', $this->defaultMimeType);
// Also check that JSON works and the routing system selects the correct
// REST route.
$this->enableService('entity:node', 'GET', 'json');
$this->httpRequest('node/' . $node->id(), 'GET', NULL, 'application/json');
$this->httpRequest($node->urlInfo(), 'GET', NULL, 'application/json');
$this->assertResponse(200);
$this->assertHeader('Content-type', 'application/json');
@ -69,7 +70,7 @@ class NodeTest extends RESTTestBase {
$data = array(
'_links' => array(
'type' => array(
'href' => _url('rest/type/node/resttest', array('absolute' => TRUE)),
'href' => Url::fromUri('base://rest/type/node/resttest', array('absolute' => TRUE))->toString(),
),
),
'title' => array(
@ -79,7 +80,7 @@ class NodeTest extends RESTTestBase {
),
);
$serialized = $this->container->get('serializer')->serialize($data, $this->defaultFormat);
$this->httpRequest('node/' . $node->id(), 'PATCH', $serialized, $this->defaultMimeType);
$this->httpRequest($node->urlInfo(), 'PATCH', $serialized, $this->defaultMimeType);
$this->assertResponse(204);
// Reload the node from the DB and check if the title was correctly updated.

View File

@ -64,7 +64,7 @@ abstract class RESTTestBase extends WebTestBase {
* Helper function to issue a HTTP request with simpletest's cURL.
*
* @param string|\Drupal\Core\Url $url
* A relative URL string or a Url object.
* A Url object or system path.
* @param string $method
* HTTP method, one of GET, POST, PUT or DELETE.
* @param array $body
@ -81,13 +81,7 @@ abstract class RESTTestBase extends WebTestBase {
$token = $this->drupalGet('rest/session/token');
}
// Convert to absolute URL.
if ($url instanceof Url) {
$url = $url->setAbsolute()->toString();
}
else {
$url = _url($url, array('absolute' => TRUE));
}
$url = $this->buildUrl($url);
switch ($method) {
case 'GET':

View File

@ -7,6 +7,8 @@
namespace Drupal\search\Tests;
use Drupal\Core\Url;
/**
* Verify the search config settings form.
*
@ -19,7 +21,7 @@ class SearchConfigSettingsFormTest extends SearchTestBase {
*
* @var array
*/
public static $modules = array('block', 'search_extra_type');
public static $modules = array('block', 'search_extra_type', 'test_page_test');
/**
* User who can search and administer search.
@ -269,8 +271,8 @@ class SearchConfigSettingsFormTest extends SearchTestBase {
// Ensure both search pages have their tabs displayed.
$this->drupalGet('search');
$elements = $this->xpath('//*[contains(@class, :class)]//a', array(':class' => 'tabs primary'));
$this->assertIdentical((string) $elements[0]['href'], _url('search/' . $first['path']));
$this->assertIdentical((string) $elements[1]['href'], _url('search/' . $second['path']));
$this->assertIdentical((string) $elements[0]['href'], Url::fromRoute('search.view_' . $first_id)->toString());
$this->assertIdentical((string) $elements[1]['href'], Url::fromRoute('search.view_' . $second_id)->toString());
// Switch the weight of the search pages and check the order of the tabs.
$edit = array(
@ -280,8 +282,8 @@ class SearchConfigSettingsFormTest extends SearchTestBase {
$this->drupalPostForm('admin/config/search/pages', $edit, t('Save configuration'));
$this->drupalGet('search');
$elements = $this->xpath('//*[contains(@class, :class)]//a', array(':class' => 'tabs primary'));
$this->assertIdentical((string) $elements[0]['href'], _url('search/' . $second['path']));
$this->assertIdentical((string) $elements[1]['href'], _url('search/' . $first['path']));
$this->assertIdentical((string) $elements[0]['href'], Url::fromRoute('search.view_' . $second_id)->toString());
$this->assertIdentical((string) $elements[1]['href'], Url::fromRoute('search.view_' . $first_id)->toString());
// Check the initial state of the search pages.
$this->drupalGet('admin/config/search/pages');

View File

@ -23,7 +23,7 @@ class SearchKeywordsConditionsTest extends SearchTestBase {
*
* @var array
*/
public static $modules = array('comment', 'search_extra_type');
public static $modules = array('comment', 'search_extra_type', 'test_page_test');
/**
* A user with permission to search and post comments.

View File

@ -4,3 +4,6 @@ description: 'Support module for Search module testing.'
package: Testing
version: VERSION
core: 8.x
dependencies:
- test_page_test

View File

@ -9,6 +9,8 @@ namespace Drupal\search_extra_type\Plugin\Search;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\UrlGeneratorTrait;
use Drupal\Core\Url;
use Drupal\search\Plugin\ConfigurableSearchPluginBase;
/**
@ -21,6 +23,8 @@ use Drupal\search\Plugin\ConfigurableSearchPluginBase;
*/
class SearchExtraTypeSearch extends ConfigurableSearchPluginBase {
use UrlGeneratorTrait;
/**
* {@inheritdoc}
*/
@ -57,7 +61,7 @@ class SearchExtraTypeSearch extends ConfigurableSearchPluginBase {
}
return array(
array(
'link' => _url('node'),
'link' => Url::fromRoute('test_page_test.test_page')->toString(),
'type' => 'Dummy result type',
'title' => 'Dummy title',
'snippet' => SafeMarkup::set("Dummy search snippet to display. Keywords: {$this->keywords}\n\nConditions: " . print_r($this->searchParameters, TRUE)),

View File

@ -6,6 +6,8 @@
namespace Drupal\serialization\Tests;
use Drupal\Core\Url;
/**
* Tests that entities references can be resolved.
*
@ -30,6 +32,9 @@ class EntityResolverTest extends NormalizerTestBase {
protected function setUp() {
parent::setUp();
$this->installSchema('system', 'router');
\Drupal::service('router.builder')->rebuild();
// Create the test field storage.
entity_create('field_storage_config', array(
'entity_type' => 'entity_test_mulrev',
@ -58,16 +63,16 @@ class EntityResolverTest extends NormalizerTestBase {
$entity->set('field_test_entity_reference', array(array('target_id' => 1)));
$entity->save();
$field_uri = _url('rest/relation/entity_test_mulrev/entity_test_mulrev/field_test_entity_reference', array('absolute' => TRUE));
$field_uri = Url::fromUri('base://rest/relation/entity_test_mulrev/entity_test_mulrev/field_test_entity_reference', array('absolute' => TRUE))->toString();
$data = array(
'_links' => array(
'type' => array(
'href' => _url('rest/type/entity_test_mulrev/entity_test_mulrev', array('absolute' => TRUE)),
'href' => Url::fromUri('base://rest/type/entity_test_mulrev/entity_test_mulrev', array('absolute' => TRUE))->toString(),
),
$field_uri => array(
array(
'href' => _url('entity/entity_test_mulrev/' . $entity->id()),
'href' => $entity->url(),
),
),
),
@ -75,7 +80,7 @@ class EntityResolverTest extends NormalizerTestBase {
$field_uri => array(
array(
'_links' => array(
'self' => _url('entity/entity_test_mulrev/' . $entity->id()),
'self' => $entity->url(),
),
'uuid' => array(
array(

View File

@ -7,6 +7,7 @@
namespace Drupal\simpletest\Tests;
use Drupal\Core\Url;
use Drupal\simpletest\WebTestBase;
/**
@ -76,8 +77,7 @@ class SimpleTestBrowserTest extends WebTestBase {
// @see drupal_valid_test_ua()
// Not using File API; a potential error must trigger a PHP warning.
unlink($this->siteDirectory . '/.htkey');
global $base_url;
$this->drupalGet(_url($base_url . '/core/install.php', array('external' => TRUE, 'absolute' => TRUE)));
$this->drupalGet(Url::fromUri('base://core/install.php', array('external' => TRUE, 'absolute' => TRUE))->toString());
$this->assertResponse(403, 'Cannot access install.php.');
}

View File

@ -1470,23 +1470,10 @@ abstract class WebTestBase extends TestBase {
* The retrieved HTML string, also available as $this->getRawContent()
*/
protected function drupalGet($path, array $options = array(), array $headers = array()) {
if ($path instanceof Url) {
$url = $path->setAbsolute()->toString();
}
// The URL generator service is not necessarily available yet; e.g., in
// interactive installer tests.
else if ($this->container->has('url_generator')) {
$options['absolute'] = TRUE;
$url = $this->container->get('url_generator')->generateFromPath($path, $options);
}
else {
$url = $this->getAbsoluteUrl($path);
}
// We re-using a CURL connection here. If that connection still has certain
// options set, it might change the GET into a POST. Make sure we clear out
// previous options.
$out = $this->curlExec(array(CURLOPT_HTTPGET => TRUE, CURLOPT_URL => $url, CURLOPT_NOBODY => FALSE, CURLOPT_HTTPHEADER => $headers));
$out = $this->curlExec(array(CURLOPT_HTTPGET => TRUE, CURLOPT_URL => $this->buildUrl($path, $options), CURLOPT_NOBODY => FALSE, CURLOPT_HTTPHEADER => $headers));
// Ensure that any changes to variables in the other thread are picked up.
$this->refreshVariables();
@ -1512,7 +1499,7 @@ abstract class WebTestBase extends TestBase {
* @param string $path
* Path to request AJAX from.
* @param array $options
* Array of options to pass to _url().
* Array of URL options.
* @param array $headers
* Array of headers. Eg array('Accept: application/vnd.drupal-ajax').
*
@ -1967,11 +1954,10 @@ abstract class WebTestBase extends TestBase {
*
* @see WebTestBase::getAjaxPageStatePostData()
* @see WebTestBase::curlExec()
* @see _url()
*/
protected function drupalPost($path, $accept, array $post, $options = array()) {
return $this->curlExec(array(
CURLOPT_URL => _url($path, $options + array('absolute' => TRUE)),
CURLOPT_URL => $this->buildUrl($path, $options),
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $this->serializePostValues($post),
CURLOPT_HTTPHEADER => array(
@ -2733,4 +2719,30 @@ abstract class WebTestBase extends TestBase {
return $request;
}
/**
* Builds an a absolute URL from a system path or a URL object.
*
* @param string|\Drupal\Core\Url $path
* A system path or a URL.
* @param array $options
* Options to be passed to Url::fromUri().
*
* @return string
* An absolute URL stsring.
*/
protected function buildUrl($path, array $options = array()) {
if ($path instanceof Url) {
return $path->setAbsolute()->toString();
}
// The URL generator service is not necessarily available yet; e.g., in
// interactive installer tests.
else if ($this->container->has('url_generator')) {
$options['absolute'] = TRUE;
return $this->container->get('url_generator')->generateFromPath($path, $options);
}
else {
return $this->getAbsoluteUrl($path);
}
}
}

View File

@ -8,6 +8,7 @@
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\node\NodeInterface;
/**
@ -39,7 +40,7 @@ function statistics_help($route_name, RouteMatchInterface $route_match) {
function statistics_node_view(array &$build, EntityInterface $node, EntityViewDisplayInterface $display, $view_mode) {
if (!$node->isNew() && $view_mode == 'full' && node_is_page($node) && empty($node->in_preview)) {
$build['statistics_content_counter']['#attached']['library'][] = 'statistics/drupal.statistics';
$settings = array('data' => array('nid' => $node->id()), 'url' => _url(drupal_get_path('module', 'statistics') . '/statistics.php'));
$settings = array('data' => array('nid' => $node->id()), 'url' => Url::fromUri('base://' . drupal_get_path('module', 'statistics') . '/statistics.php')->toString());
$build['statistics_content_counter']['#attached']['drupalSettings']['statistics'] = $settings;
}
}

View File

@ -480,7 +480,7 @@ function hook_local_tasks_alter(&$local_tasks) {
* - title: The localized title of the link.
* - route_name: The route name of the link.
* - route_parameters: The route parameters of the link.
* - localized_options: An array of options to pass to _url().
* - localized_options: An array of URL options.
* - (optional) weight: The weight of the link, which is used to sort the links.
*
*

View File

@ -601,7 +601,7 @@ class DbUpdateController extends ControllerBase {
);
batch_set($batch);
return batch_process('update.php/results', 'update.php/batch');
return batch_process('update.php/results', Url::fromRoute('system.db_update'));
}
/**

View File

@ -7,6 +7,7 @@
namespace Drupal\system\Tests\Cache;
use Drupal\Core\Url;
use Drupal\simpletest\WebTestBase;
use Drupal\Core\Cache\Cache;
@ -67,7 +68,7 @@ class PageCacheTagsIntegrationTest extends WebTestBase {
));
// Full node page 1.
$this->verifyPageCacheTags('node/' . $node_1->id(), array(
$this->verifyPageCacheTags($node_1->urlInfo(), array(
'rendered',
'block_view',
'config:block_list',
@ -96,7 +97,7 @@ class PageCacheTagsIntegrationTest extends WebTestBase {
));
// Full node page 2.
$this->verifyPageCacheTags('node/' . $node_2->id(), array(
$this->verifyPageCacheTags($node_2->urlInfo(), array(
'rendered',
'block_view',
'config:block_list',
@ -130,24 +131,26 @@ class PageCacheTagsIntegrationTest extends WebTestBase {
/**
* Fills page cache for the given path, verify cache tags on page cache hit.
*
* @param $path
* The Drupal page path to test.
* @param \Drupal\Core\Url $url
* The url
* @param $expected_tags
* The expected cache tags for the page cache entry of the given $path.
*/
protected function verifyPageCacheTags($path, $expected_tags) {
protected function verifyPageCacheTags(Url $url, $expected_tags) {
// @todo Change ->drupalGet() calls to just pass $url when
// https://www.drupal.org/node/2350837 gets committed
sort($expected_tags);
$this->drupalGet($path);
$this->drupalGet($url->setAbsolute()->toString());
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
$actual_tags = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Tags'));
sort($actual_tags);
$this->assertIdentical($actual_tags, $expected_tags);
$this->drupalGet($path);
$this->drupalGet($url->setAbsolute()->toString());
$actual_tags = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Tags'));
sort($actual_tags);
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
$this->assertIdentical($actual_tags, $expected_tags);
$cid_parts = array(_url($path, array('absolute' => TRUE)), 'html');
$cid_parts = array($url->setAbsolute()->toString(), 'html');
$cid = implode(':', $cid_parts);
$cache_entry = \Drupal::cache('render')->get($cid);
sort($cache_entry->tags);

View File

@ -7,6 +7,7 @@
namespace Drupal\system\Tests\Common;
use Drupal\Core\Url;
use Drupal\simpletest\WebTestBase;
/**
@ -22,15 +23,15 @@ class AddFeedTest extends WebTestBase {
function testBasicFeedAddNoTitle() {
$path = $this->randomMachineName(12);
$external_url = 'http://' . $this->randomMachineName(12) . '/' . $this->randomMachineName(12);
$fully_qualified_local_url = _url($this->randomMachineName(12), array('absolute' => TRUE));
$fully_qualified_local_url = Url::fromUri('base://' . $this->randomMachineName(12), array('absolute' => TRUE))->toString();
$path_for_title = $this->randomMachineName(12);
$external_for_title = 'http://' . $this->randomMachineName(12) . '/' . $this->randomMachineName(12);
$fully_qualified_for_title = _url($this->randomMachineName(12), array('absolute' => TRUE));
$fully_qualified_for_title = Url::fromUri('base://' . $this->randomMachineName(12), array('absolute' => TRUE))->toString();
$urls = array(
'path without title' => array(
'url' => _url($path, array('absolute' => TRUE)),
'url' => Url::fromUri('base://' . $path, array('absolute' => TRUE))->toString(),
'title' => '',
),
'external URL without title' => array(
@ -42,7 +43,7 @@ class AddFeedTest extends WebTestBase {
'title' => '',
),
'path with title' => array(
'url' => _url($path_for_title, array('absolute' => TRUE)),
'url' => Url::fromUri('base://' . $path_for_title, array('absolute' => TRUE))->toString(),
'title' => $this->randomMachineName(12),
),
'external URL with title' => array(

View File

@ -52,6 +52,8 @@ class AttachedAssetsTest extends KernelTestBase {
*/
protected function setUp() {
parent::setUp();
$this->installSchema('system', array('router'));
$this->container->get('router.builder')->rebuild();
$this->assetResolver = $this->container->get('asset.resolver');
$this->renderer = $this->container->get('renderer');

View File

@ -148,7 +148,7 @@ class RenderElementTypesTest extends KernelTestBase {
'#type' => 'more_link',
'#url' => Url::fromRoute('router_test.1'),
),
'expected' => '//div[@class="more-link"]/a[@href="' . _url('router_test/test1') . '" and text()="More"]',
'expected' => '//div[@class="more-link"]/a[@href="' . Url::fromRoute('router_test.1')->toString() . '" and text()="More"]',
),
array(
'name' => "#type 'more_link' anchor tag with a route",
@ -165,7 +165,7 @@ class RenderElementTypesTest extends KernelTestBase {
'#url' => Url::fromRoute('system.admin_content'),
'#options' => array('absolute' => TRUE),
),
'expected' => '//div[@class="more-link"]/a[@href="' . _url('admin/content', array('absolute' => TRUE)) . '" and text()="More"]',
'expected' => '//div[@class="more-link"]/a[@href="' . Url::fromRoute('system.admin_content')->setAbsolute()->toString() . '" and text()="More"]',
),
array(
'name' => "#type 'more_link' anchor tag to the front page",
@ -173,7 +173,7 @@ class RenderElementTypesTest extends KernelTestBase {
'#type' => 'more_link',
'#url' => Url::fromRoute('<front>'),
),
'expected' => '//div[@class="more-link"]/a[@href="' . _url('<front>') . '" and text()="More"]',
'expected' => '//div[@class="more-link"]/a[@href="' . Url::fromRoute('<front>')->toString() . '" and text()="More"]',
),
);

View File

@ -13,15 +13,11 @@ use Drupal\Core\Url;
use Drupal\simpletest\WebTestBase;
/**
* Confirm that _url(),
* Confirm that \Drupal\Core\Url,
* \Drupal\Component\Utility\UrlHelper::filterQueryParameters(),
* \Drupal\Component\Utility\UrlHelper::buildQuery(), and _l() work correctly
* with various input.
*
* _url() calls \Drupal::moduleHandler()->getImplementations(),
* which may issue a db query, which requires
* inheriting from a web test case rather than a unit test case.
*
* @group Common
*/
class UrlTest extends WebTestBase {
@ -36,12 +32,12 @@ class UrlTest extends WebTestBase {
$text = $this->randomMachineName();
$path = "<SCRIPT>alert('XSS')</SCRIPT>";
$link = _l($text, $path);
$sanitized_path = check_url(_url($path));
$sanitized_path = check_url(Url::fromUri('base://' . $path)->toString());
$this->assertTrue(strpos($link, $sanitized_path) !== FALSE, format_string('XSS attack @path was filtered by _l().', array('@path' => $path)));
// Test _url().
$link = _url($path);
$sanitized_path = check_url(_url($path));
// Test \Drupal\Core\Url.
$link = Url::fromUri('base://' . $path)->toString();
$sanitized_path = check_url(Url::fromUri('base://' . $path)->toString());
$this->assertTrue(strpos($link, $sanitized_path) !== FALSE, format_string('XSS attack @path was filtered by #theme', ['@path' => $path]));
}
@ -91,20 +87,20 @@ class UrlTest extends WebTestBase {
$path = 'common-test/type-link-active-class';
$this->drupalGet($path, $options_no_query);
$links = $this->xpath('//a[@href = :href and contains(@class, :class)]', array(':href' => _url($path, $options_no_query), ':class' => 'active'));
$links = $this->xpath('//a[@href = :href and contains(@class, :class)]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_no_query)->toString(), ':class' => 'active'));
$this->assertTrue(isset($links[0]), 'A link generated by _l() to the current page is marked active.');
$links = $this->xpath('//a[@href = :href and not(contains(@class, :class))]', array(':href' => _url($path, $options_query), ':class' => 'active'));
$links = $this->xpath('//a[@href = :href and not(contains(@class, :class))]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_query)->toString(), ':class' => 'active'));
$this->assertTrue(isset($links[0]), 'A link generated by _l() to the current page with a query string when the current page has no query string is not marked active.');
$this->drupalGet($path, $options_query);
$links = $this->xpath('//a[@href = :href and contains(@class, :class)]', array(':href' => _url($path, $options_query), ':class' => 'active'));
$links = $this->xpath('//a[@href = :href and contains(@class, :class)]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_query)->toString(), ':class' => 'active'));
$this->assertTrue(isset($links[0]), 'A link generated by _l() to the current page with a query string that matches the current query string is marked active.');
$links = $this->xpath('//a[@href = :href and contains(@class, :class)]', array(':href' => _url($path, $options_query_reverse), ':class' => 'active'));
$links = $this->xpath('//a[@href = :href and contains(@class, :class)]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_query_reverse)->toString(), ':class' => 'active'));
$this->assertTrue(isset($links[0]), 'A link generated by _l() to the current page with a query string that has matching parameters to the current query string but in a different order is marked active.');
$links = $this->xpath('//a[@href = :href and not(contains(@class, :class))]', array(':href' => _url($path, $options_no_query), ':class' => 'active'));
$links = $this->xpath('//a[@href = :href and not(contains(@class, :class))]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_no_query)->toString(), ':class' => 'active'));
$this->assertTrue(isset($links[0]), 'A link generated by _l() to the current page without a query string when the current page has a query string is not marked active.');
// Test adding a custom class in links produced by _l() and #type 'link'.
@ -257,30 +253,30 @@ class UrlTest extends WebTestBase {
// Verify external URL can contain a fragment.
$url = $test_url . '#drupal';
$result = _url($url);
$result = Url::fromUri($url)->toString();
$this->assertEqual($url, $result, 'External URL with fragment works without a fragment in $options.');
// Verify fragment can be overidden in an external URL.
$url = $test_url . '#drupal';
$fragment = $this->randomMachineName(10);
$result = _url($url, array('fragment' => $fragment));
$result = Url::fromUri($url, array('fragment' => $fragment))->toString();
$this->assertEqual($test_url . '#' . $fragment, $result, 'External URL fragment is overidden with a custom fragment in $options.');
// Verify external URL can contain a query string.
$url = $test_url . '?drupal=awesome';
$result = _url($url);
$result = Url::fromUri($url)->toString();
$this->assertEqual($url, $result, 'External URL with query string works without a query string in $options.');
// Verify external URL can be extended with a query string.
$url = $test_url;
$query = array($this->randomMachineName(5) => $this->randomMachineName(5));
$result = _url($url, array('query' => $query));
$result = Url::fromUri($url, array('query' => $query))->toString();
$this->assertEqual($url . '?' . http_build_query($query, '', '&'), $result, 'External URL can be extended with a query string in $options.');
// Verify query string can be extended in an external URL.
$url = $test_url . '?drupal=awesome';
$query = array($this->randomMachineName(5) => $this->randomMachineName(5));
$result = _url($url, array('query' => $query));
$result = Url::fromUri($url, array('query' => $query))->toString();
$this->assertEqual($url . '&' . http_build_query($query, '', '&'), $result, 'External URL query string can be extended with a custom query string in $options.');
}
}

View File

@ -8,6 +8,7 @@
namespace Drupal\system\Tests\Form;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Url;
use Drupal\simpletest\WebTestBase;
/**
@ -105,6 +106,6 @@ class RebuildTest extends WebTestBase {
// Ensure that the form's action is correct.
$forms = $this->xpath('//form[contains(@class, "node-page-form")]');
$this->assert(count($forms) == 1 && $forms[0]['action'] == _url('node/add/page'), 'Re-rendered form contains the correct action value.');
$this->assert(count($forms) == 1 && $forms[0]['action'] == Url::fromRoute('node.add', ['node_type' => 'page'])->toString(), 'Re-rendered form contains the correct action value.');
}
}

View File

@ -8,6 +8,7 @@
namespace Drupal\system\Tests\Menu;
use Drupal\Component\Utility\String;
use Drupal\Core\Url;
/**
* Provides test assertions for verifying breadcrumbs.
@ -68,9 +69,19 @@ trait AssertBreadcrumbTrait {
// this test would go into an infinite loop, so we need to check that too.
while ($trail && !empty($parts)) {
foreach ($trail as $path => $title) {
// If the path is empty or does not start with a leading /, assume it
// is an internal path that needs to be passed through _url().
$url = $path == '' || $path[0] != '/' ? _url($path) : $path;
// If the path is empty, generate the path from the <front> route. If
// the path does not start with a leading, then run it through
// Url::fromUri('base://')->toString() to get correct the base
// prepended.
if ($path == '') {
$url = Url::fromRoute('<front>')->toString();
}
elseif ($path[0] != '/') {
$url = Url::fromUri('base://' . $path)->toString();
}
else {
$url = $path;
}
$part = array_shift($parts);
$pass = ($pass && $part['href'] === $url && $part['text'] === String::checkPlain($title));
}

View File

@ -7,6 +7,8 @@
namespace Drupal\system\Tests\Menu;
use Drupal\Core\Url;
/**
* Provides test assertions for verifying the active menu trail.
*/
@ -35,7 +37,7 @@ trait AssertMenuActiveTrailTrait {
$part_xpath .= 'li[contains(@class, :class)]/a[contains(@href, :href) and contains(text(), :title)]';
$part_args = array(
':class' => 'active-trail',
':href' => _url($link_path),
':href' => Url::fromUri('base://' . $link_path)->toString(),
':title' => $link_title,
);
$xpath .= $this->buildXPathQuery($part_xpath, $part_args);
@ -55,7 +57,7 @@ trait AssertMenuActiveTrailTrait {
$args = array(
':class-trail' => 'active-trail',
':class-active' => 'active',
':href' => _url($active_link_path),
':href' => Url::fromUri('base://' . $active_link_path)->toString(),
':title' => $active_link_title,
);
$elements = $this->xpath($xpath, $args);

View File

@ -7,8 +7,7 @@
namespace Drupal\system\Tests\Menu;
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Url;
use Drupal\node\Entity\NodeType;
/**
@ -279,7 +278,7 @@ class BreadcrumbTest extends MenuTestBase {
// other than the breadcrumb trail.
$elements = $this->xpath('//nav[@id=:menu]/descendant::a[@href=:href]', array(
':menu' => 'block-bartik-tools',
':href' => _url($link_path),
':href' => Url::fromUri('base://' . $link_path)->toString(),
));
$this->assertTrue(count($elements) == 1, "Link to {$link_path} appears only once.");

View File

@ -7,6 +7,7 @@
namespace Drupal\system\Tests\Menu;
use Drupal\Core\Url;
use Drupal\simpletest\WebTestBase;
/**
@ -27,12 +28,12 @@ class LocalActionTest extends WebTestBase {
public function testLocalAction() {
$this->drupalGet('menu-test-local-action');
// Ensure that both menu and route based actions are shown.
$this->assertLocalAction(array(
'menu-test-local-action/dynamic-title' => 'My dynamic-title action',
'menu-test-local-action/hook_menu' => 'My hook_menu action',
'menu-test-local-action/routing' => 'My YAML discovery action',
'menu-test-local-action/routing2' => 'Title override',
));
$this->assertLocalAction([
[Url::fromRoute('menu_test.local_action4'), 'My dynamic-title action'],
[Url::fromRoute('menu_test.local_action2'), 'My hook_menu action'],
[Url::fromRoute('menu_test.local_action3'), 'My YAML discovery action'],
[Url::fromRoute('menu_test.local_action5'), 'Title override'],
]);
}
/**
@ -46,9 +47,11 @@ class LocalActionTest extends WebTestBase {
':class' => 'button-action',
));
$index = 0;
foreach ($actions as $href => $title) {
foreach ($actions as $action) {
/** @var \Drupal\Core\Url $url */
list($url, $title) = $action;
$this->assertEqual((string) $elements[$index], $title);
$this->assertEqual($elements[$index]['href'], _url($href));
$this->assertEqual($elements[$index]['href'], $url->toString());
$index++;
}
}

View File

@ -7,6 +7,7 @@
namespace Drupal\system\Tests\Menu;
use Drupal\Core\Url;
use Drupal\simpletest\WebTestBase;
/**
@ -34,7 +35,7 @@ class LocalTasksTest extends WebTestBase {
));
$this->assertTrue(count($elements), 'Local tasks found.');
foreach ($hrefs as $index => $element) {
$expected = _url($hrefs[$index]);
$expected = Url::fromUri('base://' . $hrefs[$index])->toString();
$method = ($elements[$index]['href'] == $expected ? 'pass' : 'fail');
$this->{$method}(format_string('Task @number href @value equals @expected.', array(
'@number' => $index + 1,

View File

@ -7,6 +7,7 @@
namespace Drupal\system\Tests\Menu;
use Drupal\Core\Url;
use Drupal\simpletest\WebTestBase;
/**
@ -62,7 +63,8 @@ class MenuRouterTest extends WebTestBase {
*/
protected function doTestHookMenuIntegration() {
// Generate base path with random argument.
$base_path = 'foo/' . $this->randomMachineName(8);
$machine_name = $this->randomMachineName(8);
$base_path = 'foo/' . $machine_name;
$this->drupalGet($base_path);
// Confirm correct controller activated.
$this->assertText('test1');
@ -70,8 +72,8 @@ class MenuRouterTest extends WebTestBase {
$this->assertLink('Local task A');
$this->assertLink('Local task B');
// Confirm correct local task href.
$this->assertLinkByHref(_url($base_path));
$this->assertLinkByHref(_url($base_path . '/b'));
$this->assertLinkByHref(Url::fromRoute('menu_test.router_test1', ['bar' => $machine_name])->toString());
$this->assertLinkByHref(Url::fromRoute('menu_test.router_test2', ['bar' => $machine_name])->toString());
}
/**

View File

@ -7,6 +7,7 @@
namespace Drupal\system\Tests\Menu;
use Drupal\Core\Url;
use Drupal\simpletest\WebTestBase;
/**
@ -40,7 +41,7 @@ class MenuTranslateTest extends WebTestBase {
$this->assertResponse(403);
$elements = $this->xpath('//ul[@class=:class]/li/a[@href=:href]', array(
':class' => 'tabs primary',
':href' => _url('foo/asdf'),
':href' => Url::fromRoute('menu_test.router_test1', ['bar' => 'asdf'])->toString(),
));
$this->assertTrue(empty($elements), 'No tab linking to foo/asdf found');
$this->assertNoLinkByHref('foo/asdf/b');

View File

@ -78,9 +78,9 @@ class UrlAlterFunctionalTest extends WebTestBase {
* Assert that an outbound path is altered to an expected value.
*
* @param $original
* A string with the original path that is run through _url().
* A string with the original path that is run through generateFrommPath().
* @param $final
* A string with the expected result after _url().
* A string with the expected result after generateFrommPath().
* @return
* TRUE if $original was correctly altered to $final, FALSE otherwise.
*/
@ -98,7 +98,7 @@ class UrlAlterFunctionalTest extends WebTestBase {
* @param $original
* The original path before it has been altered by inbound URL processing.
* @param $final
* A string with the expected result after _url().
* A string with the expected result.
* @return
* TRUE if $original was correctly altered to $final, FALSE otherwise.
*/

View File

@ -74,7 +74,7 @@ class TokenReplaceUnitTest extends TokenReplaceUnitTestBase {
* Tests the generation of all system site information tokens.
*/
public function testSystemSiteTokenReplacement() {
// The use of the _url() function requires the url_alias table to exist.
// The use of the \Drupal::url() method requires the url_alias table to exist.
$this->installSchema('system', 'url_alias');
$url_options = array(
'absolute' => TRUE,

View File

@ -217,7 +217,7 @@ class FunctionsTest extends WebTestBase {
$expected_links .= '<ul id="somelinks">';
$expected_links .= '<li class="a-link"><a href="' . Url::fromUri('base://a/link')->toString() . '">' . String::checkPlain('A <link>') . '</a></li>';
$expected_links .= '<li class="plain-text">' . String::checkPlain('Plain "text"') . '</li>';
$expected_links .= '<li class="front-page"><a href="' . _url('<front>') . '">' . String::checkPlain('Front page') . '</a></li>';
$expected_links .= '<li class="front-page"><a href="' . Url::fromRoute('<front>')->toString() . '">' . String::checkPlain('Front page') . '</a></li>';
$expected_links .= '<li class="router-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . String::checkPlain('Test route') . '</a></li>';
$query = array('key' => 'value');
$expected_links .= '<li class="query-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1', $query) . '">' . String::checkPlain('Query test route') . '</a></li>';
@ -256,7 +256,7 @@ class FunctionsTest extends WebTestBase {
$expected_links .= '<ul id="somelinks">';
$expected_links .= '<li class="a-link"><a href="' . Url::fromUri('base://a/link')->toString() . '">' . String::checkPlain('A <link>') . '</a></li>';
$expected_links .= '<li class="plain-text"><span class="a/class">' . String::checkPlain('Plain "text"') . '</span></li>';
$expected_links .= '<li class="front-page"><a href="' . _url('<front>') . '">' . String::checkPlain('Front page') . '</a></li>';
$expected_links .= '<li class="front-page"><a href="' . Url::fromRoute('<front>')->toString() . '">' . String::checkPlain('Front page') . '</a></li>';
$expected_links .= '<li class="router-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . String::checkPlain('Test route') . '</a></li>';
$query = array('key' => 'value');
$expected_links .= '<li class="query-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1', $query) . '">' . String::checkPlain('Query test route') . '</a></li>';
@ -271,7 +271,7 @@ class FunctionsTest extends WebTestBase {
$expected_links .= '<ul id="somelinks">';
$expected_links .= '<li class="a-link"><a href="' . Url::fromUri('base://a/link')->toString() . '">' . String::checkPlain('A <link>') . '</a></li>';
$expected_links .= '<li class="plain-text"><span class="a/class">' . String::checkPlain('Plain "text"') . '</span></li>';
$expected_links .= '<li data-drupal-link-system-path="&lt;front&gt;" class="front-page"><a href="' . _url('<front>') . '" data-drupal-link-system-path="&lt;front&gt;">' . String::checkPlain('Front page') . '</a></li>';
$expected_links .= '<li data-drupal-link-system-path="&lt;front&gt;" class="front-page"><a href="' . Url::fromRoute('<front>')->toString() . '" data-drupal-link-system-path="&lt;front&gt;">' . String::checkPlain('Front page') . '</a></li>';
$expected_links .= '<li data-drupal-link-system-path="router_test/test1" class="router-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '" data-drupal-link-system-path="router_test/test1">' . String::checkPlain('Test route') . '</a></li>';
$query = array('key' => 'value');
$encoded_query = String::checkPlain(Json::encode($query));

View File

@ -458,7 +458,7 @@ function system_authorized_run($callback, $file, $arguments = array(), $page_tit
function system_authorized_batch_process() {
$finish_url = system_authorized_get_url();
$process_url = system_authorized_batch_processing_url();
return batch_process($finish_url->toString(), $process_url->toString());
return batch_process($finish_url->toString(), $process_url);
}
/**
@ -631,7 +631,7 @@ function system_js_settings_alter(&$settings, AttachedAssetsInterface $assets) {
$pathPrefix = '';
$current_query = $request->query->all();
_url('', array('script' => &$scriptPath, 'prefix' => &$pathPrefix));
Url::fromRoute('<front>', [], array('script' => &$scriptPath, 'prefix' => &$pathPrefix))->toString();
$current_path = \Drupal::routeMatch()->getRouteName() ? Url::fromRouteMatch(\Drupal::routeMatch())->getInternalPath() : '';
$current_path_is_admin = \Drupal::service('router.admin_context')->isAdminRoute();
$path_settings = [
@ -722,11 +722,11 @@ function system_user_presave(UserInterface $account) {
/**
* Implements hook_user_login().
*/
function system_user_login($account) {
function system_user_login(UserInterface $account) {
$config = \Drupal::config('system.date');
// If the user has a NULL time zone, notify them to set a time zone.
if (!$account->getTimezone() && $config->get('timezone.user.configurable') && $config->get('timezone.user.warn')) {
drupal_set_message(t('Configure your <a href="@user-edit">account time zone setting</a>.', array('@user-edit' => _url("user/$account->id()/edit", array('query' => drupal_get_destination(), 'fragment' => 'edit-timezone')))));
drupal_set_message(t('Configure your <a href="@user-edit">account time zone setting</a>.', array('@user-edit' => $account->url('edit-form', array('query' => drupal_get_destination(), 'fragment' => 'edit-timezone')))));
}
}

View File

@ -190,7 +190,7 @@ class UpdateCoreTest extends UpdateTestBase {
function testModulePageRunCron() {
$this->setSystemInfo('8.0.0');
$this->config('update.settings')
->set('fetch.url', _url('update-test', array('absolute' => TRUE)))
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
->save();
$this->config('update_test.settings')
->set('xml_map', array('drupal' => '0.0'))
@ -208,7 +208,7 @@ class UpdateCoreTest extends UpdateTestBase {
$this->setSystemInfo('8.0.0');
// Instead of using refreshUpdateStatus(), set these manually.
$this->config('update.settings')
->set('fetch.url', _url('update-test', array('absolute' => TRUE)))
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
->save();
$this->config('update_test.settings')
->set('xml_map', array('drupal' => '0.0'))
@ -229,7 +229,7 @@ class UpdateCoreTest extends UpdateTestBase {
$this->setSystemInfo('8.0.0');
// Instead of using refreshUpdateStatus(), set these manually.
$this->config('update.settings')
->set('fetch.url', _url('update-test', array('absolute' => TRUE)))
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
->save();
$this->config('update_test.settings')
->set('xml_map', array('drupal' => '0.1'))
@ -250,7 +250,7 @@ class UpdateCoreTest extends UpdateTestBase {
$this->setSystemInfo('8.0.0');
// Instead of using refreshUpdateStatus(), set these manually.
$this->config('update.settings')
->set('fetch.url', _url('update-test', array('absolute' => TRUE)))
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
->save();
$this->config('update_test.settings')
->set('xml_map', array('drupal' => '0.2-sec'))
@ -325,7 +325,7 @@ class UpdateCoreTest extends UpdateTestBase {
$this->setSystemInfo('8.0.0');
// Instead of using refreshUpdateStatus(), set these manually.
$this->config('update.settings')
->set('fetch.url', _url('update-test', array('absolute' => TRUE)))
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
->save();
$this->config('update_test.settings')
->set('xml_map', array('drupal' => '0.1'))

View File

@ -44,7 +44,7 @@ abstract class UpdateTestBase extends WebTestBase {
protected function refreshUpdateStatus($xml_map, $url = 'update-test') {
// Tell the Update Manager module to fetch from the URL provided by
// update_test module.
$this->config('update.settings')->set('fetch.url', _url($url, array('absolute' => TRUE)))->save();
$this->config('update.settings')->set('fetch.url', Url::fromUri('base://' . $url, array('absolute' => TRUE))->toString())->save();
// Save the map for UpdateTestController::updateTest() to use.
$this->config('update_test.settings')->set('xml_map', $xml_map)->save();
// Manually check the update status.

View File

@ -7,6 +7,8 @@
namespace Drupal\update\Tests;
use Drupal\Core\Url;
/**
* Tests the Update Manager module's upload and extraction functionality.
*
@ -80,7 +82,7 @@ class UpdateUploadTest extends UpdateTestBase {
->set('xml_map', array('drupal' => '0.2-sec'))
->save();
$this->config('update.settings')
->set('fetch.url', _url('update-test', array('absolute' => TRUE)))
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
->save();
// Initialize the update status.
$this->drupalGet('admin/reports/updates');

View File

@ -11,5 +11,6 @@ update_test.update_test:
_title: 'Update test'
_controller: '\Drupal\update_test\Controller\UpdateTestController::updateTest'
version: NULL
project_name: NULL
requirements:
_access: 'TRUE'

View File

@ -38,4 +38,12 @@ interface DisplayRouterInterface {
*/
public function alterRoutes(RouteCollection $collection);
/**
* Generates an URL to this display.
*
* @return \Drupal\Core\Url
* A URL object for the display.
*/
public function getUrlInfo();
}

View File

@ -486,5 +486,15 @@ abstract class PathPluginBase extends DisplayPluginBase implements DisplayRouter
return $errors;
}
/**
* {@inheritdoc}
*/
public function getUrlInfo() {
if (strpos($this->getOption('path'), '%') !== FALSE) {
throw new \InvalidArgumentException('No placeholders supported yet.');
}
return Url::fromRoute($this->getRoute($this->view->storage->id(), $this->display['id']));
}
}

View File

@ -8,6 +8,7 @@
namespace Drupal\views\Tests;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Url;
use Drupal\views\Views;
/**
@ -66,7 +67,7 @@ class GlossaryTest extends ViewTestBase {
$this->assertResponse(200);
foreach ($nodes_per_char as $char => $count) {
$href = _url('glossary/' . $char);
$href = Url::fromRoute('view.glossary.page_1', ['arg_0' => $char])->toString();
$label = Unicode::strtoupper($char);
// Get the summary link for a certain character. Filter by label and href
// to ensure that both of them are correct.

View File

@ -8,6 +8,7 @@
namespace Drupal\views\Tests\Plugin;
use Drupal\Component\Utility\Html;
use Drupal\Core\Url;
use Drupal\views\Tests\ViewTestBase;
use Drupal\views\ViewExecutable;
use Drupal\views\Views;
@ -135,7 +136,8 @@ class ExposedFormTest extends ViewTestBase {
$this->assertFieldByXpath('//form/@id', $this->getExpectedExposedFormId($view), 'Expected form ID found.');
$expected_action = _url($view->display_handler->getUrl());
$view->setDisplay('page_1');
$expected_action = $view->display_handler->getUrlInfo()->toString();
$this->assertFieldByXPath('//form/@action', $expected_action, 'The expected value for the action attribute was found.');
// Make sure the description is shown.
$result = $this->xpath('//form//div[contains(@id, :id) and normalize-space(text())=:description]', array(':id' => 'edit-type--description', ':description' => t('Exposed description')));

View File

@ -44,7 +44,7 @@ class TokenReplaceTest extends ViewUnitTestBase {
'[view:description]' => 'Test view to token replacement tests.',
'[view:id]' => 'test_tokens',
'[view:title]' => 'Test token page',
'[view:url]' => _url('test_tokens', array('absolute' => TRUE)),
'[view:url]' => $view->getUrlInfo('page_1')->setAbsolute(TRUE)->toString(),
'[view:total-rows]' => (string) $view->total_rows,
'[view:base-table]' => 'views_test_data',
'[view:base-field]' => 'id',

View File

@ -9,6 +9,7 @@ namespace Drupal\views\Tests\Wizard;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\String;
use Drupal\Core\Url;
use Drupal\views\Views;
/**
@ -74,8 +75,8 @@ class BasicTest extends WizardTestBase {
$this->assertText($node2->label());
// Check if we have the feed.
$this->assertLinkByHref(_url($view2['page[feed_properties][path]']));
$elements = $this->cssSelect('link[href="' . _url($view2['page[feed_properties][path]'], ['absolute' => TRUE]) . '"]');
$this->assertLinkByHref(Url::fromRoute('view.' . $view2['id'] . '.feed_1')->toString());
$elements = $this->cssSelect('link[href="' . Url::fromRoute('view.' . $view2['id'] . '.feed_1', [], ['absolute' => TRUE])->toString() . '"]');
$this->assertEqual(count($elements), 1, 'Feed found.');
$this->drupalGet($view2['page[feed_properties][path]']);
$this->assertRaw('<rss version="2.0"');
@ -90,7 +91,7 @@ class BasicTest extends WizardTestBase {
$this->drupalGet('admin/structure/views');
$this->assertText($view2['label']);
$this->assertText($view2['description']);
$this->assertLinkByHref(_url($view2['page[path]']));
$this->assertLinkByHref(Url::fromRoute('view.' . $view2['id'] . '.page_1')->toString());
// The view should not have a REST export display.
$this->assertNoText('REST export', 'If only the page option was enabled in the wizard, the resulting view does not have a REST export display.');
@ -125,7 +126,7 @@ class BasicTest extends WizardTestBase {
$this->drupalGet('admin/structure/views');
$this->assertText($view3['label']);
$this->assertText($view3['description']);
$this->assertLinkByHref(_url($view3['page[path]']));
$this->assertLinkByHref(Url::fromRoute('view.' . $view3['id'] . '.page_1')->toString());
// The view should not have a REST export display.
$this->assertNoText('REST export', 'If only the page and block options were enabled in the wizard, the resulting view does not have a REST export display.');

View File

@ -8,6 +8,7 @@
namespace Drupal\views\Tests\Wizard;
use Drupal\Component\Utility\String;
use Drupal\Core\Url;
/**
* Tests the ability of the views wizard to put views in a menu.
@ -40,7 +41,7 @@ class MenuTest extends WizardTestBase {
$this->drupalGet('');
$this->assertResponse(200);
$this->assertLink($view['page[link_properties][title]']);
$this->assertLinkByHref(_url($view['page[path]']));
$this->assertLinkByHref(Url::fromUri('base://' . $view['page[path]'])->toString());
// Make sure the link is associated with the main menu.
/** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */

View File

@ -11,6 +11,7 @@ use Drupal\Component\Utility\String;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Form\FormState;
use Drupal\Core\Session\AccountInterface;
use Drupal\views\Plugin\views\display\DisplayRouterInterface;
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\ViewEntityInterface;
use Drupal\Component\Utility\Tags;
@ -1757,6 +1758,26 @@ class ViewExecutable {
return implode('/', $pieces);
}
/**
* Gets the Url object associated with the display handler.
*
* @param string $display_id
* (Optional) The display id. ( Used only to detail an exception. )
*
* @throws \InvalidArgumentException
* Thrown when the display plugin does not have a URL to return.
*
* @return \Drupal\Core\Url
* The display handlers URL object.
*/
public function getUrlInfo($display_id = '') {
$this->initDisplay();
if (!$this->display_handler instanceof DisplayRouterInterface) {
throw new \InvalidArgumentException(String::format('You cannot generate a URL for the display @display_id', ['@display_id' => $display_id]));
}
return $this->display_handler->getUrlInfo();
}
/**
* Get the base path used for this view.
*/

View File

@ -7,6 +7,8 @@
namespace Drupal\views_ui\Tests;
use Drupal\Core\Url;
/**
* Tests enabling, disabling, and reverting default views via the listing page.
*
@ -168,7 +170,7 @@ class DefaultViewsTest extends UITestBase {
// Check that a dynamic path is shown as text.
$this->assertRaw('test_route_with_suffix/%/suffix');
$this->assertNoLinkByHref(_url('test_route_with_suffix/%/suffix'));
$this->assertNoLinkByHref(Url::fromUri('base://test_route_with_suffix/%/suffix')->toString());
}
/**

View File

@ -292,7 +292,7 @@ class DrupalTest extends UnitTestCase {
}
/**
* Tests the _url() method.
* Tests the url() method.
*
* @covers ::url
* @see \Drupal\Core\Routing\UrlGeneratorInterface::generateFromRoute()

View File

@ -152,7 +152,7 @@ class EntityUrlTest extends UnitTestCase {
}
/**
* Tests the _url() method.
* Tests the url() method.
*
* @covers ::url
*/

View File

@ -73,6 +73,7 @@ class UnroutedUrlAssemblerTest extends UnitTestCase {
* @dataProvider providerTestAssembleWithExternalUrl
*/
public function testAssembleWithExternalUrl($uri, array $options, $expected) {
$this->setupRequestStack(FALSE);
$this->assertEquals($expected, $this->unroutedUrlAssembler->assemble($uri, $options));
}