/** * Adds linkit custom autocomplete functionality to elements. * * Instead of using the core autocomplete, we use our own. * * {@inheritdoc} * * @see \Drupal\Core\Render\Element\FormElement::processAutocomplete */ public static function processLinkitAutocomplete(&$element, FormStateInterface $form_state, &$complete_form) { $url = NULL; $access = FALSE; if (!empty($element['#autocomplete_route_name'])) { $parameters = isset($element['#autocomplete_route_parameters']) ? $element['#autocomplete_route_parameters'] : array(); $url = Url::fromRoute($element['#autocomplete_route_name'], $parameters)->toString(TRUE); /** @var \Drupal\Core\Access\AccessManagerInterface $access_manager */ $access_manager = \Drupal::service('access_manager'); $access = $access_manager->checkNamedRoute($element['#autocomplete_route_name'], $parameters, \Drupal::currentUser(), TRUE); } if ($access) { $metadata = BubbleableMetadata::createFromRenderArray($element); if ($access->isAllowed()) { $element['#attributes']['class'][] = 'form-linkit-autocomplete'; $metadata->addAttachments(['library' => ['linkit/linkit.autocomplete']]); // Provide a data attribute for the JavaScript behavior to bind to. $element['#attributes']['data-autocomplete-path'] = $url->getGeneratedUrl(); $metadata = $metadata->merge($url); } $metadata ->merge(BubbleableMetadata::createFromObject($access)) ->applyTo($element); } return $element; }
/** * Tests the generation of all system site information tokens. */ public function testSystemSiteTokenReplacement() { $url_options = array('absolute' => TRUE, 'language' => $this->interfaceLanguage); $slogan = '<blink>Slogan</blink>'; $safe_slogan = Xss::filterAdmin($slogan); // Set a few site variables. $config = $this->config('system.site'); $config->set('name', '<strong>Drupal<strong>')->set('slogan', $slogan)->set('mail', '*****@*****.**')->save(); // Generate and test tokens. $tests = array(); $tests['[site:name]'] = Html::escape($config->get('name')); $tests['[site:slogan]'] = $safe_slogan; $tests['[site:mail]'] = $config->get('mail'); $tests['[site:url]'] = \Drupal::url('<front>', [], $url_options); $tests['[site:url-brief]'] = preg_replace(array('!^https?://!', '!/$!'), '', \Drupal::url('<front>', [], $url_options)); $tests['[site:login-url]'] = \Drupal::url('user.page', [], $url_options); $base_bubbleable_metadata = new BubbleableMetadata(); $metadata_tests = []; $metadata_tests['[site:name]'] = BubbleableMetadata::createFromObject(\Drupal::config('system.site')); $metadata_tests['[site:slogan]'] = BubbleableMetadata::createFromObject(\Drupal::config('system.site')); $metadata_tests['[site:mail]'] = BubbleableMetadata::createFromObject(\Drupal::config('system.site')); $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[site:url]'] = $bubbleable_metadata->addCacheContexts(['url.site']); $metadata_tests['[site:url-brief]'] = $bubbleable_metadata; $metadata_tests['[site:login-url]'] = $bubbleable_metadata; // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { $bubbleable_metadata = new BubbleableMetadata(); $output = $this->tokenService->replace($input, array(), array('langcode' => $this->interfaceLanguage->getId()), $bubbleable_metadata); $this->assertEqual($output, $expected, new FormattableMarkup('System site information token %token replaced.', ['%token' => $input])); $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]); } }
/** * Tests core token replacements generated from a view. */ function testTokenReplacement() { $token_handler = \Drupal::token(); $view = Views::getView('test_tokens'); $view->setDisplay('page_1'); $this->executeView($view); $expected = array('[view:label]' => 'Test tokens', '[view:description]' => 'Test view to token replacement tests.', '[view:id]' => 'test_tokens', '[view:title]' => 'Test token page', '[view:url]' => $view->getUrl(NULL, 'page_1')->setAbsolute(TRUE)->toString(), '[view:total-rows]' => (string) $view->total_rows, '[view:base-table]' => 'views_test_data', '[view:base-field]' => 'id', '[view:items-per-page]' => '10', '[view:current-page]' => '1', '[view:page-count]' => '1'); $base_bubbleable_metadata = BubbleableMetadata::createFromObject($view->storage); $metadata_tests = []; $metadata_tests['[view:label]'] = $base_bubbleable_metadata; $metadata_tests['[view:description]'] = $base_bubbleable_metadata; $metadata_tests['[view:id]'] = $base_bubbleable_metadata; $metadata_tests['[view:title]'] = $base_bubbleable_metadata; $metadata_tests['[view:url]'] = $base_bubbleable_metadata; $metadata_tests['[view:total-rows]'] = $base_bubbleable_metadata; $metadata_tests['[view:base-table]'] = $base_bubbleable_metadata; $metadata_tests['[view:base-field]'] = $base_bubbleable_metadata; $metadata_tests['[view:items-per-page]'] = $base_bubbleable_metadata; $metadata_tests['[view:current-page]'] = $base_bubbleable_metadata; $metadata_tests['[view:page-count]'] = $base_bubbleable_metadata; foreach ($expected as $token => $expected_output) { $bubbleable_metadata = new BubbleableMetadata(); $output = $token_handler->replace($token, array('view' => $view), [], $bubbleable_metadata); $this->assertIdentical($output, $expected_output, format_string('Token %token replaced correctly.', array('%token' => $token))); $this->assertEqual($bubbleable_metadata, $metadata_tests[$token]); } }
/** * Bubbles Twig template argument's cacheability & attachment metadata. * * For example: a generated link or generated URL object is passed as a Twig * template argument, and its bubbleable metadata must be bubbled. * * @see \Drupal\Core\GeneratedLink * @see \Drupal\Core\GeneratedUrl * * @param mixed $arg * A Twig template argument that is about to be printed. * * @see \Drupal\Core\Theme\ThemeManager::render() * @see \Drupal\Core\Render\RendererInterface::render() */ protected function bubbleArgMetadata($arg) { // If it's a renderable, then it'll be up to the generated render array it // returns to contain the necessary cacheability & attachment metadata. If // it doesn't implement CacheableDependencyInterface or AttachmentsInterface // then there is nothing to do here. if ($arg instanceof RenderableInterface || !($arg instanceof CacheableDependencyInterface || $arg instanceof AttachmentsInterface)) { return; } $arg_bubbleable = []; BubbleableMetadata::createFromObject($arg)->applyTo($arg_bubbleable); $this->renderer->render($arg_bubbleable); }
/** * Creates some terms and a node, then tests the tokens generated from them. */ function testTaxonomyTokenReplacement() { $token_service = \Drupal::token(); $language_interface = \Drupal::languageManager()->getCurrentLanguage(); // Create two taxonomy terms. $term1 = $this->createTerm($this->vocabulary); $term2 = $this->createTerm($this->vocabulary); // Edit $term2, setting $term1 as parent. $edit = array(); $edit['name[0][value]'] = '<blink>Blinking Text</blink>'; $edit['parent[]'] = array($term1->id()); $this->drupalPostForm('taxonomy/term/' . $term2->id() . '/edit', $edit, t('Save')); // Create node with term2. $edit = array(); $node = $this->drupalCreateNode(array('type' => 'article')); $edit[$this->fieldName . '[]'] = $term2->id(); $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); // Generate and test sanitized tokens for term1. $tests = array(); $tests['[term:tid]'] = $term1->id(); $tests['[term:name]'] = Html::escape($term1->getName()); $tests['[term:description]'] = $term1->description->processed; $tests['[term:url]'] = $term1->url('canonical', array('absolute' => TRUE)); $tests['[term:node-count]'] = 0; $tests['[term:parent:name]'] = '[term:parent:name]'; $tests['[term:vocabulary:name]'] = Html::escape($this->vocabulary->label()); $tests['[term:vocabulary]'] = Html::escape($this->vocabulary->label()); $base_bubbleable_metadata = BubbleableMetadata::createFromObject($term1); $metadata_tests = array(); $metadata_tests['[term:tid]'] = $base_bubbleable_metadata; $metadata_tests['[term:name]'] = $base_bubbleable_metadata; $metadata_tests['[term:description]'] = $base_bubbleable_metadata; $metadata_tests['[term:url]'] = $base_bubbleable_metadata; $metadata_tests['[term:node-count]'] = $base_bubbleable_metadata; $metadata_tests['[term:parent:name]'] = $base_bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[term:vocabulary:name]'] = $bubbleable_metadata->addCacheTags($this->vocabulary->getCacheTags()); $metadata_tests['[term:vocabulary]'] = $bubbleable_metadata->addCacheTags($this->vocabulary->getCacheTags()); foreach ($tests as $input => $expected) { $bubbleable_metadata = new BubbleableMetadata(); $output = $token_service->replace($input, array('term' => $term1), array('langcode' => $language_interface->getId()), $bubbleable_metadata); $this->assertEqual($output, $expected, format_string('Sanitized taxonomy term token %token replaced.', array('%token' => $input))); $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]); } // Generate and test sanitized tokens for term2. $tests = array(); $tests['[term:tid]'] = $term2->id(); $tests['[term:name]'] = Html::escape($term2->getName()); $tests['[term:description]'] = $term2->description->processed; $tests['[term:url]'] = $term2->url('canonical', array('absolute' => TRUE)); $tests['[term:node-count]'] = 1; $tests['[term:parent:name]'] = Html::escape($term1->getName()); $tests['[term:parent:url]'] = $term1->url('canonical', array('absolute' => TRUE)); $tests['[term:parent:parent:name]'] = '[term:parent:parent:name]'; $tests['[term:vocabulary:name]'] = Html::escape($this->vocabulary->label()); // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { $output = $token_service->replace($input, array('term' => $term2), array('langcode' => $language_interface->getId())); $this->assertEqual($output, $expected, format_string('Sanitized taxonomy term token %token replaced.', array('%token' => $input))); } // Generate and test unsanitized tokens. $tests['[term:name]'] = $term2->getName(); $tests['[term:description]'] = $term2->getDescription(); $tests['[term:parent:name]'] = $term1->getName(); $tests['[term:vocabulary:name]'] = $this->vocabulary->label(); foreach ($tests as $input => $expected) { $output = $token_service->replace($input, array('term' => $term2), array('langcode' => $language_interface->getId(), 'sanitize' => FALSE)); $this->assertEqual($output, $expected, format_string('Unsanitized taxonomy term token %token replaced.', array('%token' => $input))); } // Generate and test sanitized tokens. $tests = array(); $tests['[vocabulary:vid]'] = $this->vocabulary->id(); $tests['[vocabulary:name]'] = Html::escape($this->vocabulary->label()); $tests['[vocabulary:description]'] = Xss::filter($this->vocabulary->getDescription()); $tests['[vocabulary:node-count]'] = 1; $tests['[vocabulary:term-count]'] = 2; // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { $output = $token_service->replace($input, array('vocabulary' => $this->vocabulary), array('langcode' => $language_interface->getId())); $this->assertEqual($output, $expected, format_string('Sanitized taxonomy vocabulary token %token replaced.', array('%token' => $input))); } // Generate and test unsanitized tokens. $tests['[vocabulary:name]'] = $this->vocabulary->label(); $tests['[vocabulary:description]'] = $this->vocabulary->getDescription(); foreach ($tests as $input => $expected) { $output = $token_service->replace($input, array('vocabulary' => $this->vocabulary), array('langcode' => $language_interface->getId(), 'sanitize' => FALSE)); $this->assertEqual($output, $expected, format_string('Unsanitized taxonomy vocabulary token %token replaced.', array('%token' => $input))); } }
/** * Creates a comment, then tests the tokens generated from it. */ function testCommentTokenReplacement() { $token_service = \Drupal::token(); $language_interface = \Drupal::languageManager()->getCurrentLanguage(); $url_options = array('absolute' => TRUE, 'language' => $language_interface); // Change the title of the admin user. $this->adminUser->name->value = 'This is a title with some special & > " stuff.'; $this->adminUser->save(); $this->drupalLogin($this->adminUser); // Set comment variables. $this->setCommentSubject(TRUE); // Create a node and a comment. $node = $this->drupalCreateNode(['type' => 'article', 'title' => '<script>alert("123")</script>']); $parent_comment = $this->postComment($node, $this->randomMachineName(), $this->randomMachineName(), TRUE); // Post a reply to the comment. $this->drupalGet('comment/reply/node/' . $node->id() . '/comment/' . $parent_comment->id()); $child_comment = $this->postComment(NULL, $this->randomMachineName(), $this->randomMachineName()); $comment = Comment::load($child_comment->id()); $comment->setHomepage('http://example.org/'); // Add HTML to ensure that sanitation of some fields tested directly. $comment->setSubject('<blink>Blinking Comment</blink>'); // Generate and test tokens. $tests = array(); $tests['[comment:cid]'] = $comment->id(); $tests['[comment:hostname]'] = $comment->getHostname(); $tests['[comment:author]'] = Html::escape($comment->getAuthorName()); $tests['[comment:mail]'] = $this->adminUser->getEmail(); $tests['[comment:homepage]'] = UrlHelper::filterBadProtocol($comment->getHomepage()); $tests['[comment:title]'] = Html::escape($comment->getSubject()); $tests['[comment:body]'] = $comment->comment_body->processed; $tests['[comment:langcode]'] = $comment->language()->getId(); $tests['[comment:url]'] = $comment->url('canonical', $url_options + array('fragment' => 'comment-' . $comment->id())); $tests['[comment:edit-url]'] = $comment->url('edit-form', $url_options); $tests['[comment:created]'] = \Drupal::service('date.formatter')->format($comment->getCreatedTime(), 'medium', array('langcode' => $language_interface->getId())); $tests['[comment:created:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($comment->getCreatedTime(), array('langcode' => $language_interface->getId())); $tests['[comment:changed:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($comment->getChangedTimeAcrossTranslations(), array('langcode' => $language_interface->getId())); $tests['[comment:parent:cid]'] = $comment->hasParentComment() ? $comment->getParentComment()->id() : NULL; $tests['[comment:parent:title]'] = $parent_comment->getSubject(); $tests['[comment:entity]'] = Html::escape($node->getTitle()); // Test node specific tokens. $tests['[comment:entity:nid]'] = $comment->getCommentedEntityId(); $tests['[comment:entity:title]'] = Html::escape($node->getTitle()); $tests['[comment:author:uid]'] = $comment->getOwnerId(); $tests['[comment:author:name]'] = Html::escape($this->adminUser->getDisplayName()); $base_bubbleable_metadata = BubbleableMetadata::createFromObject($comment); $metadata_tests = []; $metadata_tests['[comment:cid]'] = $base_bubbleable_metadata; $metadata_tests['[comment:hostname]'] = $base_bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; $bubbleable_metadata->addCacheableDependency($this->adminUser); $metadata_tests['[comment:author]'] = $bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; $bubbleable_metadata->addCacheableDependency($this->adminUser); $metadata_tests['[comment:mail]'] = $bubbleable_metadata; $metadata_tests['[comment:homepage]'] = $base_bubbleable_metadata; $metadata_tests['[comment:title]'] = $base_bubbleable_metadata; $metadata_tests['[comment:body]'] = $base_bubbleable_metadata; $metadata_tests['[comment:langcode]'] = $base_bubbleable_metadata; $metadata_tests['[comment:url]'] = $base_bubbleable_metadata; $metadata_tests['[comment:edit-url]'] = $base_bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[comment:created]'] = $bubbleable_metadata->addCacheTags(['rendered']); $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[comment:created:since]'] = $bubbleable_metadata->setCacheMaxAge(0); $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[comment:changed:since]'] = $bubbleable_metadata->setCacheMaxAge(0); $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[comment:parent:cid]'] = $bubbleable_metadata->addCacheTags(['comment:1']); $metadata_tests['[comment:parent:title]'] = $bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[comment:entity]'] = $bubbleable_metadata->addCacheTags(['node:2']); // Test node specific tokens. $metadata_tests['[comment:entity:nid]'] = $bubbleable_metadata; $metadata_tests['[comment:entity:title]'] = $bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[comment:author:uid]'] = $bubbleable_metadata->addCacheTags(['user:2']); $metadata_tests['[comment:author:name]'] = $bubbleable_metadata; // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { $bubbleable_metadata = new BubbleableMetadata(); $output = $token_service->replace($input, array('comment' => $comment), array('langcode' => $language_interface->getId()), $bubbleable_metadata); $this->assertEqual($output, $expected, new FormattableMarkup('Comment token %token replaced.', ['%token' => $input])); $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]); } // Test anonymous comment author. $author_name = 'This is a random & " > string'; $comment->setOwnerId(0)->setAuthorName($author_name); $input = '[comment:author]'; $output = $token_service->replace($input, array('comment' => $comment), array('langcode' => $language_interface->getId())); $this->assertEqual($output, Html::escape($author_name), format_string('Comment author token %token replaced.', array('%token' => $input))); // Load node so comment_count gets computed. $node = Node::load($node->id()); // Generate comment tokens for the node (it has 2 comments, both new). $tests = array(); $tests['[entity:comment-count]'] = 2; $tests['[entity:comment-count-new]'] = 2; foreach ($tests as $input => $expected) { $output = $token_service->replace($input, array('entity' => $node, 'node' => $node), array('langcode' => $language_interface->getId())); $this->assertEqual($output, $expected, format_string('Node comment token %token replaced.', array('%token' => $input))); } }
/** * Creates a file, then tests the tokens generated from it. */ function testFileTokenReplacement() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); $token_service = \Drupal::token(); $language_interface = \Drupal::languageManager()->getCurrentLanguage(); // Create file field. $type_name = 'article'; $field_name = 'field_' . strtolower($this->randomMachineName()); $this->createFileField($field_name, 'node', $type_name); $test_file = $this->getTestFile('text'); // Coping a file to test uploads with non-latin filenames. $filename = drupal_dirname($test_file->getFileUri()) . '/текстовый файл.txt'; $test_file = file_copy($test_file, $filename); // Create a new node with the uploaded file. $nid = $this->uploadNodeFile($test_file, $field_name, $type_name); // Load the node and the file. $node_storage->resetCache(array($nid)); $node = $node_storage->load($nid); $file = File::load($node->{$field_name}->target_id); // Generate and test sanitized tokens. $tests = array(); $tests['[file:fid]'] = $file->id(); $tests['[file:name]'] = SafeMarkup::checkPlain($file->getFilename()); $tests['[file:path]'] = SafeMarkup::checkPlain($file->getFileUri()); $tests['[file:mime]'] = SafeMarkup::checkPlain($file->getMimeType()); $tests['[file:size]'] = format_size($file->getSize()); $tests['[file:url]'] = SafeMarkup::checkPlain(file_create_url($file->getFileUri())); $tests['[file:created]'] = format_date($file->getCreatedTime(), 'medium', '', NULL, $language_interface->getId()); $tests['[file:created:short]'] = format_date($file->getCreatedTime(), 'short', '', NULL, $language_interface->getId()); $tests['[file:changed]'] = format_date($file->getChangedTime(), 'medium', '', NULL, $language_interface->getId()); $tests['[file:changed:short]'] = format_date($file->getChangedTime(), 'short', '', NULL, $language_interface->getId()); $tests['[file:owner]'] = SafeMarkup::checkPlain(user_format_name($this->adminUser)); $tests['[file:owner:uid]'] = $file->getOwnerId(); $base_bubbleable_metadata = BubbleableMetadata::createFromObject($file); $metadata_tests = []; $metadata_tests['[file:fid]'] = $base_bubbleable_metadata; $metadata_tests['[file:name]'] = $base_bubbleable_metadata; $metadata_tests['[file:path]'] = $base_bubbleable_metadata; $metadata_tests['[file:mime]'] = $base_bubbleable_metadata; $metadata_tests['[file:size]'] = $base_bubbleable_metadata; $metadata_tests['[file:url]'] = $base_bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[file:created]'] = $bubbleable_metadata->addCacheTags(['rendered']); $metadata_tests['[file:created:short]'] = $bubbleable_metadata; $metadata_tests['[file:changed]'] = $bubbleable_metadata; $metadata_tests['[file:changed:short]'] = $bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[file:owner]'] = $bubbleable_metadata->addCacheTags(['user:2']); $metadata_tests['[file:owner:uid]'] = $bubbleable_metadata; // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { $bubbleable_metadata = new BubbleableMetadata(); $output = $token_service->replace($input, array('file' => $file), array('langcode' => $language_interface->getId()), $bubbleable_metadata); $this->assertEqual($output, $expected, format_string('Sanitized file token %token replaced.', array('%token' => $input))); $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]); } // Generate and test unsanitized tokens. $tests['[file:name]'] = $file->getFilename(); $tests['[file:path]'] = $file->getFileUri(); $tests['[file:mime]'] = $file->getMimeType(); $tests['[file:size]'] = format_size($file->getSize()); foreach ($tests as $input => $expected) { $output = $token_service->replace($input, array('file' => $file), array('langcode' => $language_interface->getId(), 'sanitize' => FALSE)); $this->assertEqual($output, $expected, format_string('Unsanitized file token %token replaced.', array('%token' => $input))); } }
/** * Creates a user, then tests the tokens generated from it. */ function testUserTokenReplacement() { $token_service = \Drupal::token(); $language_interface = \Drupal::languageManager()->getCurrentLanguage(); $url_options = array('absolute' => TRUE, 'language' => $language_interface); \Drupal::state()->set('user_hooks_test_user_format_name_alter', TRUE); \Drupal::state()->set('user_hooks_test_user_format_name_alter_safe', TRUE); // Create two users and log them in one after another. $user1 = $this->drupalCreateUser(array()); $user2 = $this->drupalCreateUser(array()); $this->drupalLogin($user1); $this->drupalLogout(); $this->drupalLogin($user2); $account = User::load($user1->id()); $global_account = User::load(\Drupal::currentUser()->id()); // Generate and test tokens. $tests = array(); $tests['[user:uid]'] = $account->id(); $tests['[user:name]'] = $account->getAccountName(); $tests['[user:account-name]'] = $account->getAccountName(); $tests['[user:display-name]'] = $account->getDisplayName(); $tests['[user:mail]'] = $account->getEmail(); $tests['[user:url]'] = $account->url('canonical', $url_options); $tests['[user:edit-url]'] = $account->url('edit-form', $url_options); $tests['[user:last-login]'] = format_date($account->getLastLoginTime(), 'medium', '', NULL, $language_interface->getId()); $tests['[user:last-login:short]'] = format_date($account->getLastLoginTime(), 'short', '', NULL, $language_interface->getId()); $tests['[user:created]'] = format_date($account->getCreatedTime(), 'medium', '', NULL, $language_interface->getId()); $tests['[user:created:short]'] = format_date($account->getCreatedTime(), 'short', '', NULL, $language_interface->getId()); $tests['[current-user:name]'] = $global_account->getAccountName(); $tests['[current-user:account-name]'] = $global_account->getAccountName(); $tests['[current-user:display-name]'] = $global_account->getDisplayName(); $base_bubbleable_metadata = BubbleableMetadata::createFromObject($account); $metadata_tests = []; $metadata_tests['[user:uid]'] = $base_bubbleable_metadata; $metadata_tests['[user:name]'] = $base_bubbleable_metadata; $metadata_tests['[user:account-name]'] = $base_bubbleable_metadata; $metadata_tests['[user:display-name]'] = $base_bubbleable_metadata; $metadata_tests['[user:mail]'] = $base_bubbleable_metadata; $metadata_tests['[user:url]'] = $base_bubbleable_metadata; $metadata_tests['[user:edit-url]'] = $base_bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; // This test runs with the Language module enabled, which means config is // overridden by LanguageConfigFactoryOverride (to provide translations of // config). This causes the interface language cache context to be added for // config entities. The four next tokens use DateFormat Config entities, and // therefore have the interface language cache context. $bubbleable_metadata->addCacheContexts(['languages:language_interface']); $metadata_tests['[user:last-login]'] = $bubbleable_metadata->addCacheTags(['rendered']); $metadata_tests['[user:last-login:short]'] = $bubbleable_metadata; $metadata_tests['[user:created]'] = $bubbleable_metadata; $metadata_tests['[user:created:short]'] = $bubbleable_metadata; $metadata_tests['[current-user:name]'] = $base_bubbleable_metadata->merge(BubbleableMetadata::createFromObject($global_account)->addCacheContexts(['user'])); $metadata_tests['[current-user:account-name]'] = $base_bubbleable_metadata->merge(BubbleableMetadata::createFromObject($global_account)->addCacheContexts(['user'])); $metadata_tests['[current-user:display-name]'] = $base_bubbleable_metadata->merge(BubbleableMetadata::createFromObject($global_account)->addCacheContexts(['user'])); // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { $bubbleable_metadata = new BubbleableMetadata(); $output = $token_service->replace($input, ['user' => $account], ['langcode' => $language_interface->getId()], $bubbleable_metadata); $this->assertEqual($output, $expected, new FormattableMarkup('User token %token replaced.', ['%token' => $input])); $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]); } // Generate tokens for the anonymous user. $anonymous_user = User::load(0); $tests = []; $tests['[user:uid]'] = t('not yet assigned'); $tests['[user:display-name]'] = $anonymous_user->getDisplayName(); $base_bubbleable_metadata = BubbleableMetadata::createFromObject($anonymous_user); $metadata_tests = []; $metadata_tests['[user:uid]'] = $base_bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; $bubbleable_metadata->addCacheableDependency(\Drupal::config('user.settings')); $metadata_tests['[user:display-name]'] = $bubbleable_metadata; foreach ($tests as $input => $expected) { $bubbleable_metadata = new BubbleableMetadata(); $output = $token_service->replace($input, array('user' => $anonymous_user), array('langcode' => $language_interface->getId()), $bubbleable_metadata); $this->assertEqual($output, $expected, format_string('Sanitized user token %token replaced.', array('%token' => $input))); $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]); } // Generate login and cancel link. $tests = array(); $tests['[user:one-time-login-url]'] = user_pass_reset_url($account); $tests['[user:cancel-url]'] = user_cancel_url($account); // Generate tokens with interface language. $link = \Drupal::url('user.page', [], array('absolute' => TRUE)); foreach ($tests as $input => $expected) { $output = $token_service->replace($input, ['user' => $account], ['langcode' => $language_interface->getId(), 'callback' => 'user_mail_tokens', 'clear' => TRUE]); $this->assertTrue(strpos($output, $link) === 0, 'Generated URL is in interface language.'); } // Generate tokens with the user's preferred language. $account->preferred_langcode = 'de'; $account->save(); $link = \Drupal::url('user.page', [], array('language' => \Drupal::languageManager()->getLanguage($account->getPreferredLangcode()), 'absolute' => TRUE)); foreach ($tests as $input => $expected) { $output = $token_service->replace($input, ['user' => $account], ['callback' => 'user_mail_tokens', 'clear' => TRUE]); $this->assertTrue(strpos($output, $link) === 0, "Generated URL is in the user's preferred language."); } // Generate tokens with one specific language. $link = \Drupal::url('user.page', [], array('language' => \Drupal::languageManager()->getLanguage('de'), 'absolute' => TRUE)); foreach ($tests as $input => $expected) { foreach (array($user1, $user2) as $account) { $output = $token_service->replace($input, ['user' => $account], ['langcode' => 'de', 'callback' => 'user_mail_tokens', 'clear' => TRUE]); $this->assertTrue(strpos($output, $link) === 0, "Generated URL in the requested language."); } } // Generate user display name tokens when safe markup is returned. // @see user_hooks_test_user_format_name_alter() \Drupal::state()->set('user_hooks_test_user_format_name_alter_safe', TRUE); $input = '[user:display-name] [current-user:display-name]'; $expected = "<em>{$user1->id()}</em> <em>{$user2->id()}</em>"; $output = $token_service->replace($input, ['user' => $user1]); $this->assertEqual($output, $expected, new FormattableMarkup('User token %token does not escape safe markup.', ['%token' => 'display-name'])); }
/** * Creates a node, then tests the tokens generated from it. */ function testNodeTokenReplacement() { $url_options = array('absolute' => TRUE, 'language' => $this->interfaceLanguage); // Create a user and a node. $account = $this->createUser(); /* @var $node \Drupal\node\NodeInterface */ $node = Node::create(['type' => 'article', 'tnid' => 0, 'uid' => $account->id(), 'title' => '<blink>Blinking Text</blink>', 'body' => [['value' => 'Regular NODE body for the test.', 'summary' => 'Fancy NODE summary.', 'format' => 'plain_text']]]); $node->save(); // Generate and test tokens. $tests = array(); $tests['[node:nid]'] = $node->id(); $tests['[node:vid]'] = $node->getRevisionId(); $tests['[node:type]'] = 'article'; $tests['[node:type-name]'] = 'Article'; $tests['[node:title]'] = Html::escape($node->getTitle()); $tests['[node:body]'] = $node->body->processed; $tests['[node:summary]'] = $node->body->summary_processed; $tests['[node:langcode]'] = $node->language()->getId(); $tests['[node:url]'] = $node->url('canonical', $url_options); $tests['[node:edit-url]'] = $node->url('edit-form', $url_options); $tests['[node:author]'] = $account->getUsername(); $tests['[node:author:uid]'] = $node->getOwnerId(); $tests['[node:author:name]'] = $account->getUsername(); $tests['[node:created:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getCreatedTime(), array('langcode' => $this->interfaceLanguage->getId())); $tests['[node:changed:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getChangedTime(), array('langcode' => $this->interfaceLanguage->getId())); $base_bubbleable_metadata = BubbleableMetadata::createFromObject($node); $metadata_tests = []; $metadata_tests['[node:nid]'] = $base_bubbleable_metadata; $metadata_tests['[node:vid]'] = $base_bubbleable_metadata; $metadata_tests['[node:type]'] = $base_bubbleable_metadata; $metadata_tests['[node:type-name]'] = $base_bubbleable_metadata; $metadata_tests['[node:title]'] = $base_bubbleable_metadata; $metadata_tests['[node:body]'] = $base_bubbleable_metadata; $metadata_tests['[node:summary]'] = $base_bubbleable_metadata; $metadata_tests['[node:langcode]'] = $base_bubbleable_metadata; $metadata_tests['[node:url]'] = $base_bubbleable_metadata; $metadata_tests['[node:edit-url]'] = $base_bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[node:author]'] = $bubbleable_metadata->addCacheTags(['user:1']); $metadata_tests['[node:author:uid]'] = $bubbleable_metadata; $metadata_tests['[node:author:name]'] = $bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[node:created:since]'] = $bubbleable_metadata->setCacheMaxAge(0); $metadata_tests['[node:changed:since]'] = $bubbleable_metadata; // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { $bubbleable_metadata = new BubbleableMetadata(); $output = $this->tokenService->replace($input, array('node' => $node), array('langcode' => $this->interfaceLanguage->getId()), $bubbleable_metadata); $this->assertEqual($output, $expected, format_string('Node token %token replaced.', ['%token' => $input])); $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]); } // Repeat for a node without a summary. $node = Node::create(['type' => 'article', 'uid' => $account->id(), 'title' => '<blink>Blinking Text</blink>', 'body' => [['value' => 'A string that looks random like TR5c2I', 'format' => 'plain_text']]]); $node->save(); // Generate and test token - use full body as expected value. $tests = array(); $tests['[node:summary]'] = $node->body->processed; // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated for node without a summary.'); foreach ($tests as $input => $expected) { $output = $this->tokenService->replace($input, array('node' => $node), array('language' => $this->interfaceLanguage)); $this->assertEqual($output, $expected, new FormattableMarkup('Node token %token replaced for node without a summary.', ['%token' => $input])); } }
/** * {@inheritdoc} */ public function render(ResultRow $row) { $access = $this->checkUrlAccess($row); $build = ['#markup' => $access->isAllowed() ? $this->renderLink($row) : '']; BubbleableMetadata::createFromObject($access)->applyTo($build); return $build; }
/** * Asserts \Drupal\Core\Routing\UrlGenerator::generateFromRoute()'s output. * * @param $route_name * The route name to test. * @param array $route_parameters * The route parameters to test. * @param array $options * The options to test. * @param $expected_url * The expected generated URL string. * @param \Drupal\Core\Render\BubbleableMetadata $expected_bubbleable_metadata * The expected generated bubbleable metadata. */ protected function assertGenerateFromRoute($route_name, array $route_parameters, array $options, $expected_url, BubbleableMetadata $expected_bubbleable_metadata) { // First, test with $collect_cacheability_metadata set to the default value. $url = $this->generator->generateFromRoute($route_name, $route_parameters, $options); $this->assertSame($expected_url, $url); // Second, test with it set to TRUE. $generated_url = $this->generator->generateFromRoute($route_name, $route_parameters, $options, TRUE); $this->assertSame($expected_url, $generated_url->getGeneratedUrl()); $this->assertEquals($expected_bubbleable_metadata, BubbleableMetadata::createFromObject($generated_url)); }
/** * Creates a support_ticket, then tests the tokens generated from it. */ function testSupportTicketTokenReplacement() { $url_options = array('absolute' => TRUE, 'language' => $this->interfaceLanguage); // Create a user and a support_ticket. $account = $this->createUser(); /* @var $support_ticket \Drupal\support_ticket\SupportTicketInterface */ $support_ticket = entity_create('support_ticket', array('support_ticket_type' => 'test', 'uid' => $account->id(), 'title' => '<blink>Blinking Text</blink>', 'body' => [['value' => 'Regular SUPPORT TICKET body for the test.', 'summary' => 'Fancy SUPPORT TICKET summary.', 'format' => 'plain_text']])); $support_ticket->save(); // Generate and test tokens. $tests = array(); $tests['[support_ticket:stid]'] = $support_ticket->id(); $tests['[support_ticket:vid]'] = $support_ticket->getRevisionId(); $tests['[support_ticket:type]'] = 'test'; $tests['[support_ticket:type-name]'] = 'Test'; $tests['[support_ticket:title]'] = Html::escape($support_ticket->getTitle()); $tests['[support_ticket:body]'] = $support_ticket->body->processed; //$tests['[support_ticket:summary]'] = $support_ticket->body->summary_processed; $tests['[support_ticket:langcode]'] = $support_ticket->language()->getId(); $tests['[support_ticket:url]'] = $support_ticket->url('canonical', $url_options); $tests['[support_ticket:edit-url]'] = $support_ticket->url('edit-form', $url_options); $tests['[support_ticket:author]'] = $account->getUsername(); $tests['[support_ticket:author:uid]'] = $support_ticket->getOwnerId(); $tests['[support_ticket:author:name]'] = $account->getUsername(); $tests['[support_ticket:created:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($support_ticket->getCreatedTime(), array('langcode' => $this->interfaceLanguage->getId())); $tests['[support_ticket:changed:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($support_ticket->getChangedTime(), array('langcode' => $this->interfaceLanguage->getId())); $base_bubbleable_metadata = BubbleableMetadata::createFromObject($support_ticket); $metadata_tests = []; $metadata_tests['[support_ticket:stid]'] = $base_bubbleable_metadata; $metadata_tests['[support_ticket:vid]'] = $base_bubbleable_metadata; $metadata_tests['[support_ticket:type]'] = $base_bubbleable_metadata; $metadata_tests['[support_ticket:type-name]'] = $base_bubbleable_metadata; $metadata_tests['[support_ticket:title]'] = $base_bubbleable_metadata; $metadata_tests['[support_ticket:body]'] = $base_bubbleable_metadata; //$metadata_tests['[support_ticket:summary]'] = $base_bubbleable_metadata; $metadata_tests['[support_ticket:langcode]'] = $base_bubbleable_metadata; $metadata_tests['[support_ticket:url]'] = $base_bubbleable_metadata; $metadata_tests['[support_ticket:edit-url]'] = $base_bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[support_ticket:author]'] = $bubbleable_metadata->addCacheTags(['user:1']); $metadata_tests['[support_ticket:author:uid]'] = $bubbleable_metadata; $metadata_tests['[support_ticket:author:name]'] = $bubbleable_metadata; $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[support_ticket:created:since]'] = $bubbleable_metadata->setCacheMaxAge(0); $metadata_tests['[support_ticket:changed:since]'] = $bubbleable_metadata; // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { $bubbleable_metadata = new BubbleableMetadata(); $output = $this->tokenService->replace($input, array('support_ticket' => $support_ticket), array('langcode' => $this->interfaceLanguage->getId()), $bubbleable_metadata); $this->assertEqual($output, $expected, format_string('Support_ticket token %token replaced.', ['%token' => $input])); $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]); } // Repeat for a support_ticket without a summary. $support_ticket = entity_create('support_ticket', array('support_ticket_type' => 'test', 'uid' => $account->id(), 'title' => '<blink>Blinking Text</blink>', 'body' => [['value' => 'A string that looks random like TR5c2I', 'format' => 'plain_text']])); $support_ticket->save(); // Generate and test token - use full body as expected value. $tests = array(); // @todo: Find an appropriate way to do the rest of these tests. //$tests['[support_ticket:summary]'] = $support_ticket->body->processed; // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated for support_ticket without a summary.'); foreach ($tests as $input => $expected) { $output = $this->tokenService->replace($input, array('support_ticket' => $support_ticket), array('language' => $this->interfaceLanguage)); $this->assertEqual($output, $expected, new FormattableMarkup('Support_ticket token %token replaced for support_ticket without a summary.', ['%token' => $input])); } }
/** * Tests the generation of all system site information tokens. */ public function testSystemSiteTokenReplacement() { // The use of the \Drupal::url() method requires the url_alias table to exist. $this->installSchema('system', 'url_alias'); $url_options = array('absolute' => TRUE, 'language' => $this->interfaceLanguage); $slogan = '<blink>Slogan</blink>'; $safe_slogan = Xss::filterAdmin($slogan); // Set a few site variables. $config = $this->config('system.site'); $config->set('name', '<strong>Drupal<strong>')->set('slogan', $slogan)->set('mail', '*****@*****.**')->save(); // Generate and test sanitized tokens. $tests = array(); $tests['[site:name]'] = SafeMarkup::checkPlain($config->get('name')); $tests['[site:slogan]'] = $safe_slogan; $tests['[site:mail]'] = $config->get('mail'); $tests['[site:url]'] = \Drupal::url('<front>', [], $url_options); $tests['[site:url-brief]'] = preg_replace(array('!^https?://!', '!/$!'), '', \Drupal::url('<front>', [], $url_options)); $tests['[site:login-url]'] = \Drupal::url('user.page', [], $url_options); $base_bubbleable_metadata = new BubbleableMetadata(); $metadata_tests = []; $metadata_tests['[site:name]'] = BubbleableMetadata::createFromObject(\Drupal::config('system.site')); $metadata_tests['[site:slogan]'] = BubbleableMetadata::createFromObject(\Drupal::config('system.site')); $metadata_tests['[site:mail]'] = BubbleableMetadata::createFromObject(\Drupal::config('system.site')); $bubbleable_metadata = clone $base_bubbleable_metadata; $metadata_tests['[site:url]'] = $bubbleable_metadata->addCacheContexts(['url.site']); $metadata_tests['[site:url-brief]'] = $bubbleable_metadata; $metadata_tests['[site:login-url]'] = $bubbleable_metadata; // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { $bubbleable_metadata = new BubbleableMetadata(); $output = $this->tokenService->replace($input, array(), array('langcode' => $this->interfaceLanguage->getId()), $bubbleable_metadata); $this->assertEqual($output, $expected, format_string('Sanitized system site information token %token replaced.', array('%token' => $input))); $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]); } // Generate and test unsanitized tokens. $tests['[site:name]'] = $config->get('name'); $tests['[site:slogan]'] = $config->get('slogan'); foreach ($tests as $input => $expected) { $output = $this->tokenService->replace($input, array(), array('langcode' => $this->interfaceLanguage->getId(), 'sanitize' => FALSE), $bubbleable_metadata); $this->assertEqual($output, $expected, format_string('Unsanitized system site information token %token replaced.', array('%token' => $input))); } // Check that the results of Token::generate are sanitized properly. This // does NOT test the cleanliness of every token -- just that the $sanitize // flag is being passed properly through the call stack and being handled // correctly by a 'known' token, [site:slogan]. $raw_tokens = array('slogan' => '[site:slogan]'); $generated = $this->tokenService->generate('site', $raw_tokens, [], [], $bubbleable_metadata); $this->assertEqual($generated['[site:slogan]'], $safe_slogan, 'Token sanitized.'); $generated = $this->tokenService->generate('site', $raw_tokens, array(), array('sanitize' => FALSE), $bubbleable_metadata); $this->assertEqual($generated['[site:slogan]'], $slogan, 'Unsanitized token generated properly.'); }
/** * Merges an object's cacheable metadata into the variables array. * * @param \Drupal\Core\Cache\CacheableDependencyInterface|mixed $object * The object whose cacheability metadata to retrieve. If it implements * CacheableDependencyInterface, its cacheability metadata will be used, * otherwise, the passed in object must be assumed to be uncacheable, so * max-age 0 is set. * * @return $this */ public function bubbleObject($object) { BubbleableMetadata::createFromRenderArray($this->array)->merge(BubbleableMetadata::createFromObject($object))->applyTo($this->array); return $this; }