Пример #1
0
 /**
  * Gets the list of links used by this field.
  *
  * @return array
  *   The links which are used by the render function.
  */
 protected function getLinks()
 {
     $links = array();
     foreach ($this->options['fields'] as $field) {
         if (empty($this->view->field[$field]->last_render_text)) {
             continue;
         }
         $title = $this->view->field[$field]->last_render_text;
         $path = '';
         $url = NULL;
         if (!empty($this->view->field[$field]->options['alter']['path'])) {
             $path = $this->view->field[$field]->options['alter']['path'];
         } elseif (!empty($this->view->field[$field]->options['alter']['url']) && $this->view->field[$field]->options['alter']['url'] instanceof UrlObject) {
             $url = $this->view->field[$field]->options['alter']['url'];
         }
         // Make sure that tokens are replaced for this paths as well.
         $tokens = $this->getRenderTokens(array());
         $path = strip_tags(String::decodeEntities($this->viewsTokenReplace($path, $tokens)));
         $links[$field] = array('url' => $path ? UrlObject::fromUri('internal:/' . $path) : $url, 'title' => $title);
         if (!empty($this->options['destination'])) {
             $links[$field]['query'] = drupal_get_destination();
         }
     }
     return $links;
 }
 /**
  * {@inheritdoc}
  */
 public function process($text, $langcode)
 {
     $result = new FilterProcessResult($text);
     if (stristr($text, 'data-caption') !== FALSE) {
         $dom = Html::load($text);
         $xpath = new \DOMXPath($dom);
         foreach ($xpath->query('//*[@data-caption]') as $node) {
             // Read the data-caption attribute's value, then delete it.
             $caption = String::checkPlain($node->getAttribute('data-caption'));
             $node->removeAttribute('data-caption');
             // Sanitize caption: decode HTML encoding, limit allowed HTML tags; only
             // allow inline tags that are allowed by default, plus <br>.
             $caption = String::decodeEntities($caption);
             $caption = Xss::filter($caption, array('a', 'em', 'strong', 'cite', 'code', 'br'));
             // The caption must be non-empty.
             if (Unicode::strlen($caption) === 0) {
                 continue;
             }
             // Given the updated node and caption: re-render it with a caption, but
             // bubble up the value of the class attribute of the captioned element,
             // this allows it to collaborate with e.g. the filter_align filter.
             $classes = $node->getAttribute('class');
             $node->removeAttribute('class');
             $filter_caption = array('#theme' => 'filter_caption', '#node' => SafeMarkup::set($node->C14N()), '#tag' => $node->tagName, '#caption' => $caption, '#classes' => $classes);
             $altered_html = drupal_render($filter_caption);
             // Load the altered HTML into a new DOMDocument and retrieve the element.
             $updated_node = Html::load($altered_html)->getElementsByTagName('body')->item(0)->childNodes->item(0);
             // Import the updated node from the new DOMDocument into the original
             // one, importing also the child nodes of the updated node.
             $updated_node = $dom->importNode($updated_node, TRUE);
             // Finally, replace the original image node with the new image node!
             $node->parentNode->replaceChild($updated_node, $node);
         }
         $result->setProcessedText(Html::serialize($dom))->addAssets(array('library' => array('filter/caption')));
     }
     return $result;
 }
 /**
  * Returns matched labels based on a given search string.
  *
  * @param string $target_type
  *   The ID of the target entity type.
  * @param string $selection_handler
  *   The plugin ID of the entity reference selection handler.
  * @param array $selection_settings
  *   An array of settings that will be passed to the selection handler.
  * @param string $string
  *   (optional) The label of the entity to query by.
  *
  * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
  *   Thrown when the current user doesn't have access to the specifies entity.
  *
  * @return array
  *   An array of matched entity labels, in the format required by the AJAX
  *   autocomplete API (e.g. array('value' => $value, 'label' => $label)).
  *
  * @see \Drupal\system\Controller\EntityAutocompleteController
  */
 public function getMatches($target_type, $selection_handler, $selection_settings, $string = '')
 {
     $matches = array();
     $options = array('target_type' => $target_type, 'handler' => $selection_handler, 'handler_settings' => $selection_settings);
     $handler = $this->selectionManager->getInstance($options);
     if (isset($string)) {
         // Get an array of matching entities.
         $match_operator = !empty($selection_settings['match_operator']) ? $selection_settings['match_operator'] : 'CONTAINS';
         $entity_labels = $handler->getReferenceableEntities($string, $match_operator, 10);
         // Loop through the entities and convert them into autocomplete output.
         foreach ($entity_labels as $values) {
             foreach ($values as $entity_id => $label) {
                 $key = "{$label} ({$entity_id})";
                 // Strip things like starting/trailing white spaces, line breaks and
                 // tags.
                 $key = preg_replace('/\\s\\s+/', ' ', str_replace("\n", '', trim(String::decodeEntities(strip_tags($key)))));
                 // Names containing commas or quotes must be wrapped in quotes.
                 $key = Tags::encode($key);
                 $matches[] = array('value' => $key, 'label' => $label);
             }
         }
     }
     return $matches;
 }
Пример #4
0
 /**
  * Asserts that text transformed to lowercase with HTML entities decoded does not contain a given string.
  *
  * Otherwise fails the test with a given message, similar to all the
  * SimpleTest assert* functions.
  *
  * Note that this does not remove nulls, new lines, and other character that
  * could be used to obscure a tag or an attribute name.
  *
  * @param $haystack
  *   Text to look in.
  * @param $needle
  *   Lowercase, plain text to look for.
  * @param $message
  *   (optional) Message to display if failed. Defaults to an empty string.
  * @param $group
  *   (optional) The group this message belongs to. Defaults to 'Other'.
  * @return
  *   TRUE on pass, FALSE on fail.
  */
 function assertNoNormalized($haystack, $needle, $message = '', $group = 'Other')
 {
     return $this->assertTrue(strpos(strtolower(String::decodeEntities($haystack)), $needle) === FALSE, $message, $group);
 }
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     parent::submitForm($form, $form_state);
     /** @var \Drupal\comment\CommentInterface $comment */
     $comment = $this->entity;
     // If the comment was posted by a registered user, assign the author's ID.
     // @todo Too fragile. Should be prepared and stored in comment_form()
     // already.
     $author_name = $comment->getAuthorName();
     if (!$comment->is_anonymous && !empty($author_name) && ($account = user_load_by_name($author_name))) {
         $comment->setOwner($account);
     }
     // If the comment was posted by an anonymous user and no author name was
     // required, use "Anonymous" by default.
     if ($comment->is_anonymous && (!isset($author_name) || $author_name === '')) {
         $comment->setAuthorName($this->config('user.settings')->get('anonymous'));
     }
     // Validate the comment's subject. If not specified, extract from comment
     // body.
     if (trim($comment->getSubject()) == '') {
         // The body may be in any format, so:
         // 1) Filter it into HTML
         // 2) Strip out all HTML tags
         // 3) Convert entities back to plain-text.
         $comment_text = $comment->comment_body->processed;
         $comment->setSubject(Unicode::truncate(trim(String::decodeEntities(strip_tags($comment_text))), 29, TRUE));
         // Edge cases where the comment body is populated only by HTML tags will
         // require a default subject.
         if ($comment->getSubject() == '') {
             $comment->setSubject($this->t('(No subject)'));
         }
     }
     return $comment;
 }
Пример #6
0
 /**
  * Sanitizes the HTML select element's options.
  *
  * The function is recursive to support optgroups.
  */
 protected function prepareFilterSelectOptions(&$options)
 {
     foreach ($options as $value => $label) {
         // Recurse for optgroups.
         if (is_array($label)) {
             $this->prepareFilterSelectOptions($options[$value]);
         } elseif (is_object($label) && isset($label->option)) {
             $this->prepareFilterSelectOptions($options[$value]->option);
         } else {
             // Cast the label to a string since it can be an object.
             // @see \Drupal\Core\StringTranslation\TranslationWrapper
             $options[$value] = strip_tags(UtilityString::decodeEntities((string) $label));
         }
     }
 }
Пример #7
0
 /**
  * Checks for meta refresh tag and if found call drupalGet() recursively.
  *
  * This function looks for the http-equiv attribute to be set to "Refresh" and
  * is case-sensitive.
  *
  * @return
  *   Either the new page content or FALSE.
  */
 protected function checkForMetaRefresh()
 {
     if (strpos($this->getRawContent(), '<meta ') && $this->parse()) {
         $refresh = $this->xpath('//meta[@http-equiv="Refresh"]');
         if (!empty($refresh)) {
             // Parse the content attribute of the meta tag for the format:
             // "[delay]: URL=[page_to_redirect_to]".
             if (preg_match('/\\d+;\\s*URL=(?<url>.*)/i', $refresh[0]['content'], $match)) {
                 return $this->drupalGet($this->getAbsoluteUrl(String::decodeEntities($match['url'])));
             }
         }
     }
     return FALSE;
 }
Пример #8
0
 /**
  * Build all the arguments.
  */
 protected function _buildArguments()
 {
     // Initially, we want to build sorts and fields. This can change, though,
     // if we get a summary view.
     if (empty($this->argument)) {
         return TRUE;
     }
     // build arguments.
     $position = -1;
     $substitutions = array();
     $status = TRUE;
     // Get the title.
     $title = $this->display_handler->getOption('title');
     // Iterate through each argument and process.
     foreach ($this->argument as $id => $arg) {
         $position++;
         $argument = $this->argument[$id];
         if ($argument->broken()) {
             continue;
         }
         $argument->setRelationship();
         $arg = isset($this->args[$position]) ? $this->args[$position] : NULL;
         $argument->position = $position;
         if (isset($arg) || $argument->hasDefaultArgument()) {
             if (!isset($arg)) {
                 $arg = $argument->getDefaultArgument();
                 // make sure default args get put back.
                 if (isset($arg)) {
                     $this->args[$position] = $arg;
                 }
                 // remember that this argument was computed, not passed on the URL.
                 $argument->is_default = TRUE;
             }
             // Set the argument, which will also validate that the argument can be set.
             if (!$argument->setArgument($arg)) {
                 $status = $argument->validateFail($arg);
                 break;
             }
             if ($argument->isException()) {
                 $arg_title = $argument->exceptionTitle();
             } else {
                 $arg_title = $argument->getTitle();
                 $argument->query($this->display_handler->useGroupBy());
             }
             // Add this argument's substitution
             $substitutions['%' . ($position + 1)] = $arg_title;
             $substitutions['!' . ($position + 1)] = strip_tags(String::decodeEntities($arg));
             // Test to see if we should use this argument's title
             if (!empty($argument->options['title_enable']) && !empty($argument->options['title'])) {
                 $title = $argument->options['title'];
             }
         } else {
             // determine default condition and handle.
             $status = $argument->defaultAction();
             break;
         }
         // Be safe with references and loops:
         unset($argument);
     }
     // set the title in the build info.
     if (!empty($title)) {
         $this->build_info['title'] = $title;
     }
     // Store the arguments for later use.
     $this->build_info['substitutions'] = $substitutions;
     return $status;
 }
Пример #9
0
 /**
  * {@inheritdoc}
  */
 public function process($text, $langcode)
 {
     $result = new FilterProcessResult($text);
     if (stristr($text, 'data-caption') !== FALSE || stristr($text, 'data-align') !== FALSE) {
         $caption_found = FALSE;
         $dom = Html::load($text);
         $xpath = new \DOMXPath($dom);
         foreach ($xpath->query('//*[@data-caption or @data-align]') as $node) {
             $caption = NULL;
             $align = NULL;
             // Retrieve, then remove the data-caption and data-align attributes.
             if ($node->hasAttribute('data-caption')) {
                 $caption = String::checkPlain($node->getAttribute('data-caption'));
                 $node->removeAttribute('data-caption');
                 // Sanitize caption: decode HTML encoding, limit allowed HTML tags;
                 // only allow inline tags that are allowed by default, plus <br>.
                 $caption = String::decodeEntities($caption);
                 $caption = Xss::filter($caption, array('a', 'em', 'strong', 'cite', 'code', 'br'));
                 // The caption must be non-empty.
                 if (Unicode::strlen($caption) === 0) {
                     $caption = NULL;
                 }
             }
             if ($node->hasAttribute('data-align')) {
                 $align = $node->getAttribute('data-align');
                 $node->removeAttribute('data-align');
                 // Only allow 3 values: 'left', 'center' and 'right'.
                 if (!in_array($align, array('left', 'center', 'right'))) {
                     $align = NULL;
                 }
             }
             // Don't transform the HTML if there isn't a caption after validation.
             if ($caption === NULL) {
                 // If there is a valid alignment, then transform the data-align
                 // attribute to a corresponding alignment class.
                 if ($align !== NULL) {
                     $classes = $node->getAttribute('class');
                     $classes = strlen($classes) > 0 ? explode(' ', $classes) : array();
                     $classes[] = 'align-' . $align;
                     $node->setAttribute('class', implode(' ', $classes));
                 }
                 continue;
             } else {
                 $caption_found = TRUE;
             }
             // Given the updated node, caption and alignment: re-render it with a
             // caption.
             $filter_caption = array('#theme' => 'filter_caption', '#node' => SafeMarkup::set($node->C14N()), '#tag' => $node->tagName, '#caption' => $caption, '#align' => $align);
             $altered_html = drupal_render($filter_caption);
             // Load the altered HTML into a new DOMDocument and retrieve the element.
             $updated_node = Html::load($altered_html)->getElementsByTagName('body')->item(0)->childNodes->item(0);
             // Import the updated node from the new DOMDocument into the original
             // one, importing also the child nodes of the updated node.
             $updated_node = $dom->importNode($updated_node, TRUE);
             // Finally, replace the original image node with the new image node!
             $node->parentNode->replaceChild($updated_node, $node);
         }
         $result->setProcessedText(Html::serialize($dom));
         if ($caption_found) {
             $result->addAssets(array('library' => array('filter/caption')));
         }
     }
     return $result;
 }
Пример #10
0
 /**
  * {@inheritdoc}
  */
 public function getArgumentsTokens()
 {
     $tokens = array();
     if (!empty($this->view->build_info['substitutions'])) {
         $tokens = $this->view->build_info['substitutions'];
     }
     // Add tokens for every argument (contextual filter) and path arg.
     $handlers = count($this->view->display_handler->getHandlers('argument'));
     for ($count = 1; $count <= $handlers; $count++) {
         if (!isset($tokens["%{$count}"])) {
             $tokens["%{$count}"] = '';
         }
         // Use strip tags as there should never be HTML in the path.
         // However, we need to preserve special characters like " that
         // were removed by String::checkPlain().
         $tokens["!{$count}"] = isset($this->view->args[$count - 1]) ? strip_tags(String::decodeEntities($this->view->args[$count - 1])) : '';
     }
     return $tokens;
 }
Пример #11
0
 /**
  * Transforms an HTML string into plain text, preserving its structure.
  *
  * The output will be suitable for use as 'format=flowed; delsp=yes' text
  * (RFC 3676) and can be passed directly to MailManagerInterface::mail() for sending.
  *
  * We deliberately use LF rather than CRLF, see MailManagerInterface::mail().
  *
  * This function provides suitable alternatives for the following tags:
  * <a> <em> <i> <strong> <b> <br> <p> <blockquote> <ul> <ol> <li> <dl> <dt>
  * <dd> <h1> <h2> <h3> <h4> <h5> <h6> <hr>
  *
  * @param string $string
  *   The string to be transformed.
  * @param array $allowed_tags
  *   (optional) If supplied, a list of tags that will be transformed. If
  *   omitted, all supported tags are transformed.
  *
  * @return string
  *   The transformed string.
  */
 public static function htmlToText($string, $allowed_tags = NULL)
 {
     // Cache list of supported tags.
     if (empty(static::$supportedTags)) {
         static::$supportedTags = array('a', 'em', 'i', 'strong', 'b', 'br', 'p', 'blockquote', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr');
     }
     // Make sure only supported tags are kept.
     $allowed_tags = isset($allowed_tags) ? array_intersect(static::$supportedTags, $allowed_tags) : static::$supportedTags;
     // Make sure tags, entities and attributes are well-formed and properly
     // nested.
     $string = Html::normalize(Xss::filter($string, $allowed_tags));
     // Apply inline styles.
     $string = preg_replace('!</?(em|i)((?> +)[^>]*)?>!i', '/', $string);
     $string = preg_replace('!</?(strong|b)((?> +)[^>]*)?>!i', '*', $string);
     // Replace inline <a> tags with the text of link and a footnote.
     // 'See <a href="http://drupal.org">the Drupal site</a>' becomes
     // 'See the Drupal site [1]' with the URL included as a footnote.
     static::htmlToMailUrls(NULL, TRUE);
     $pattern = '@(<a[^>]+?href="([^"]*)"[^>]*?>(.+?)</a>)@i';
     $string = preg_replace_callback($pattern, 'static::htmlToMailUrls', $string);
     $urls = static::htmlToMailUrls();
     $footnotes = '';
     if (count($urls)) {
         $footnotes .= "\n";
         for ($i = 0, $max = count($urls); $i < $max; $i++) {
             $footnotes .= '[' . ($i + 1) . '] ' . $urls[$i] . "\n";
         }
     }
     // Split tags from text.
     $split = preg_split('/<([^>]+?)>/', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
     // Note: PHP ensures the array consists of alternating delimiters and
     // literals and begins and ends with a literal (inserting $null as
     // required).
     // Odd/even counter (tag or no tag).
     $tag = FALSE;
     // Case conversion function.
     $casing = NULL;
     $output = '';
     // All current indentation string chunks.
     $indent = array();
     // Array of counters for opened lists.
     $lists = array();
     foreach ($split as $value) {
         // Holds a string ready to be formatted and output.
         $chunk = NULL;
         // Process HTML tags (but don't output any literally).
         if ($tag) {
             list($tagname) = explode(' ', strtolower($value), 2);
             switch ($tagname) {
                 // List counters.
                 case 'ul':
                     array_unshift($lists, '*');
                     break;
                 case 'ol':
                     array_unshift($lists, 1);
                     break;
                 case '/ul':
                 case '/ol':
                     array_shift($lists);
                     // Ensure blank new-line.
                     $chunk = '';
                     break;
                     // Quotation/list markers, non-fancy headers.
                 // Quotation/list markers, non-fancy headers.
                 case 'blockquote':
                     // Format=flowed indentation cannot be mixed with lists.
                     $indent[] = count($lists) ? ' "' : '>';
                     break;
                 case 'li':
                     $indent[] = isset($lists[0]) && is_numeric($lists[0]) ? ' ' . $lists[0]++ . ') ' : ' * ';
                     break;
                 case 'dd':
                     $indent[] = '    ';
                     break;
                 case 'h3':
                     $indent[] = '.... ';
                     break;
                 case 'h4':
                     $indent[] = '.. ';
                     break;
                 case '/blockquote':
                     if (count($lists)) {
                         // Append closing quote for inline quotes (immediately).
                         $output = rtrim($output, "> \n") . "\"\n";
                         // Ensure blank new-line.
                         $chunk = '';
                     }
                     // Fall-through.
                 // Fall-through.
                 case '/li':
                 case '/dd':
                     array_pop($indent);
                     break;
                 case '/h3':
                 case '/h4':
                     array_pop($indent);
                 case '/h5':
                 case '/h6':
                     // Ensure blank new-line.
                     $chunk = '';
                     break;
                     // Fancy headers.
                 // Fancy headers.
                 case 'h1':
                     $indent[] = '======== ';
                     $casing = '\\Drupal\\Component\\Utility\\Unicode::strtoupper';
                     break;
                 case 'h2':
                     $indent[] = '-------- ';
                     $casing = '\\Drupal\\Component\\Utility\\Unicode::strtoupper';
                     break;
                 case '/h1':
                 case '/h2':
                     $casing = NULL;
                     // Pad the line with dashes.
                     $output = static::htmlToTextPad($output, $tagname == '/h1' ? '=' : '-', ' ');
                     array_pop($indent);
                     // Ensure blank new-line.
                     $chunk = '';
                     break;
                     // Horizontal rulers.
                 // Horizontal rulers.
                 case 'hr':
                     // Insert immediately.
                     $output .= static::wrapMail('', implode('', $indent)) . "\n";
                     $output = static::htmlToTextPad($output, '-');
                     break;
                     // Paragraphs and definition lists.
                 // Paragraphs and definition lists.
                 case '/p':
                 case '/dl':
                     // Ensure blank new-line.
                     $chunk = '';
                     break;
             }
         } else {
             // Convert inline HTML text to plain text; not removing line-breaks or
             // white-space, since that breaks newlines when sanitizing plain-text.
             $value = trim(String::decodeEntities($value));
             if (Unicode::strlen($value)) {
                 $chunk = $value;
             }
         }
         // See if there is something waiting to be output.
         if (isset($chunk)) {
             // Apply any necessary case conversion.
             if (isset($casing)) {
                 $chunk = call_user_func($casing, $chunk);
             }
             $line_endings = Settings::get('mail_line_endings', PHP_EOL);
             // Format it and apply the current indentation.
             $output .= static::wrapMail($chunk, implode('', $indent)) . $line_endings;
             // Remove non-quotation markers from indentation.
             $indent = array_map('\\Drupal\\Core\\Mail\\MailFormatHelper::htmlToTextClean', $indent);
         }
         $tag = !$tag;
     }
     return $output . $footnotes;
 }
Пример #12
0
 /**
  * {@inheritdoc}
  */
 protected function sanitizeLabel(&$label)
 {
     // Select form inputs allow unencoded HTML entities, but no HTML tags.
     $label = String::decodeEntities(strip_tags($label));
 }
Пример #13
0
 /**
  * Overrides \Drupal\views\Plugin\views\field\FieldPluginBase::render().
  *
  * Renders the contextual fields.
  *
  * @param \Drupal\views\ResultRow $values
  *   The values retrieved from a single row of a view's query result.
  *
  * @see contextual_preprocess()
  * @see contextual_contextual_links_view_alter()
  */
 public function render(ResultRow $values)
 {
     $links = array();
     foreach ($this->options['fields'] as $field) {
         $rendered_field = $this->view->style_plugin->getField($values->index, $field);
         if (empty($rendered_field)) {
             continue;
         }
         $title = $this->view->field[$field]->last_render_text;
         $path = '';
         if (!empty($this->view->field[$field]->options['alter']['path'])) {
             $path = $this->view->field[$field]->options['alter']['path'];
         } elseif (!empty($this->view->field[$field]->options['alter']['url']) && $this->view->field[$field]->options['alter']['url'] instanceof Url) {
             $path = $this->view->field[$field]->options['alter']['url']->toString();
         }
         if (!empty($title) && !empty($path)) {
             // Make sure that tokens are replaced for this paths as well.
             $tokens = $this->getRenderTokens(array());
             $path = strip_tags(String::decodeEntities(strtr($path, $tokens)));
             $links[$field] = array('href' => $path, 'title' => $title);
             if (!empty($this->options['destination'])) {
                 $links[$field]['query'] = drupal_get_destination();
             }
         }
     }
     // Renders a contextual links placeholder.
     if (!empty($links)) {
         $contextual_links = array('contextual' => array('', array(), array('contextual-views-field-links' => UrlHelper::encodePath(Json::encode($links)))));
         $element = array('#type' => 'contextual_links_placeholder', '#id' => _contextual_links_to_id($contextual_links));
         return drupal_render($element);
     } else {
         return '';
     }
 }
Пример #14
0
 /**
  * Recursive function to add replacements for nested query string parameters.
  *
  * E.g. if you pass in the following array:
  *   array(
  *     'foo' => array(
  *       'a' => 'value',
  *       'b' => 'value',
  *     ),
  *     'bar' => array(
  *       'a' => 'value',
  *       'b' => array(
  *         'c' => value,
  *       ),
  *     ),
  *   );
  *
  * Would yield the following array of tokens:
  *   array(
  *     '%foo_a' => 'value'
  *     '%foo_b' => 'value'
  *     '%bar_a' => 'value'
  *     '%bar_b_c' => 'value'
  *   );
  *
  * @param $array
  *   An array of values.
  *
  * @param $parent_keys
  *   An array of parent keys. This will represent the array depth.
  *
  * @return
  *   An array of available tokens, with nested keys representative of the array structure.
  */
 protected function getTokenValuesRecursive(array $array, array $parent_keys = array())
 {
     $tokens = array();
     foreach ($array as $param => $val) {
         if (is_array($val)) {
             // Copy parent_keys array, so we don't affect other elements of this
             // iteration.
             $child_parent_keys = $parent_keys;
             $child_parent_keys[] = $param;
             // Get the child tokens.
             $child_tokens = $this->getTokenValuesRecursive($val, $child_parent_keys);
             // Add them to the current tokens array.
             $tokens += $child_tokens;
         } else {
             // Create a token key based on array element structure.
             $token_string = !empty($parent_keys) ? implode('_', $parent_keys) . '_' . $param : $param;
             $tokens['%' . $token_string] = strip_tags(String::decodeEntities($val));
         }
     }
     return $tokens;
 }
Пример #15
0
 /**
  * Tests rewriting the output to a link.
  */
 public function testAlterUrl()
 {
     $view = Views::getView('test_view');
     $view->setDisplay();
     $view->initHandlers();
     $this->executeView($view);
     $row = $view->result[0];
     $id_field = $view->field['id'];
     // Setup the general settings required to build a link.
     $id_field->options['alter']['make_link'] = TRUE;
     $id_field->options['alter']['path'] = $path = $this->randomMachineName();
     // Tests that the suffix/prefix appears on the output.
     $id_field->options['alter']['prefix'] = $prefix = $this->randomMachineName();
     $id_field->options['alter']['suffix'] = $suffix = $this->randomMachineName();
     $output = $id_field->theme($row);
     $this->assertSubString($output, $prefix);
     $this->assertSubString($output, $suffix);
     unset($id_field->options['alter']['prefix']);
     unset($id_field->options['alter']['suffix']);
     $output = $id_field->theme($row);
     $this->assertSubString($output, $path, 'Make sure that the path is part of the output');
     // Some generic test code adapted from the UrlTest class, which tests
     // mostly the different options for the path.
     global $base_url, $script_path;
     foreach (array(FALSE, TRUE) as $absolute) {
         $alter =& $id_field->options['alter'];
         $alter['path'] = 'node/123';
         $expected_result = \Drupal::url('entity.node.canonical', ['node' => '123'], ['absolute' => $absolute]);
         $alter['absolute'] = $absolute;
         $result = $id_field->theme($row);
         $this->assertSubString($result, $expected_result);
         $expected_result = \Drupal::url('entity.node.canonical', ['node' => '123'], ['fragment' => 'foo', 'absolute' => $absolute]);
         $alter['path'] = 'node/123#foo';
         $result = $id_field->theme($row);
         $this->assertSubString($result, $expected_result);
         $expected_result = \Drupal::url('entity.node.canonical', ['node' => '123'], ['query' => ['foo' => NULL], 'absolute' => $absolute]);
         $alter['path'] = 'node/123?foo';
         $result = $id_field->theme($row);
         $this->assertSubString($result, $expected_result);
         $expected_result = \Drupal::url('entity.node.canonical', ['node' => '123'], ['query' => ['foo' => 'bar', 'bar' => 'baz'], 'absolute' => $absolute]);
         $alter['path'] = 'node/123?foo=bar&bar=baz';
         $result = $id_field->theme($row);
         $this->assertSubString(String::decodeEntities($result), String::decodeEntities($expected_result));
         // @todo The route-based URL generator strips out NULL attributes.
         // $expected_result = \Drupal::url('entity.node.canonical', ['node' => '123'], ['query' => ['foo' => NULL], 'fragment' => 'bar', 'absolute' => $absolute]);
         $expected_result = \Drupal::urlGenerator()->generateFromPath('node/123', array('query' => array('foo' => NULL), 'fragment' => 'bar', 'absolute' => $absolute));
         $alter['path'] = 'node/123?foo#bar';
         $result = $id_field->theme($row);
         $this->assertSubString(String::decodeEntities($result), String::decodeEntities($expected_result));
         $expected_result = \Drupal::url('<front>', [], ['absolute' => $absolute]);
         $alter['path'] = '<front>';
         $result = $id_field->theme($row);
         $this->assertSubString($result, $expected_result);
     }
     // Tests the replace spaces with dashes feature.
     $id_field->options['alter']['replace_spaces'] = TRUE;
     $id_field->options['alter']['path'] = $path = $this->randomMachineName() . ' ' . $this->randomMachineName();
     $output = $id_field->theme($row);
     $this->assertSubString($output, str_replace(' ', '-', $path));
     $id_field->options['alter']['replace_spaces'] = FALSE;
     $output = $id_field->theme($row);
     // The url has a space in it, so to check we have to decode the url output.
     $this->assertSubString(urldecode($output), $path);
     // Tests the external flag.
     // Switch on the external flag should output an external url as well.
     $id_field->options['alter']['external'] = TRUE;
     $id_field->options['alter']['path'] = $path = 'drupal.org';
     $output = $id_field->theme($row);
     $this->assertSubString($output, 'http://drupal.org');
     // Setup a not external url, which shouldn't lead to an external url.
     $id_field->options['alter']['external'] = FALSE;
     $id_field->options['alter']['path'] = $path = 'drupal.org';
     $output = $id_field->theme($row);
     $this->assertNotSubString($output, 'http://drupal.org');
     // Tests the transforming of the case setting.
     $id_field->options['alter']['path'] = $path = $this->randomMachineName();
     $id_field->options['alter']['path_case'] = 'none';
     $output = $id_field->theme($row);
     $this->assertSubString($output, $path);
     // Switch to uppercase and lowercase.
     $id_field->options['alter']['path_case'] = 'upper';
     $output = $id_field->theme($row);
     $this->assertSubString($output, strtoupper($path));
     $id_field->options['alter']['path_case'] = 'lower';
     $output = $id_field->theme($row);
     $this->assertSubString($output, strtolower($path));
     // Switch to ucfirst and ucwords.
     $id_field->options['alter']['path_case'] = 'ucfirst';
     $id_field->options['alter']['path'] = 'drupal has a great community';
     $output = $id_field->theme($row);
     $this->assertSubString($output, UrlHelper::encodePath('Drupal has a great community'));
     $id_field->options['alter']['path_case'] = 'ucwords';
     $output = $id_field->theme($row);
     $this->assertSubString($output, UrlHelper::encodePath('Drupal Has A Great Community'));
     unset($id_field->options['alter']['path_case']);
     // Tests the linkclass setting and see whether it actuall exists in the output.
     $id_field->options['alter']['link_class'] = $class = $this->randomMachineName();
     $output = $id_field->theme($row);
     $elements = $this->xpathContent($output, '//a[contains(@class, :class)]', array(':class' => $class));
     $this->assertTrue($elements);
     // @fixme link_class, alt, rel cannot be unset, which should be fixed.
     $id_field->options['alter']['link_class'] = '';
     // Tests the alt setting.
     $id_field->options['alter']['alt'] = $rel = $this->randomMachineName();
     $output = $id_field->theme($row);
     $elements = $this->xpathContent($output, '//a[contains(@title, :alt)]', array(':alt' => $rel));
     $this->assertTrue($elements);
     $id_field->options['alter']['alt'] = '';
     // Tests the rel setting.
     $id_field->options['alter']['rel'] = $rel = $this->randomMachineName();
     $output = $id_field->theme($row);
     $elements = $this->xpathContent($output, '//a[contains(@rel, :rel)]', array(':rel' => $rel));
     $this->assertTrue($elements);
     $id_field->options['alter']['rel'] = '';
     // Tests the target setting.
     $id_field->options['alter']['target'] = $target = $this->randomMachineName();
     $output = $id_field->theme($row);
     $elements = $this->xpathContent($output, '//a[contains(@target, :target)]', array(':target' => $target));
     $this->assertTrue($elements);
     unset($id_field->options['alter']['target']);
 }
Пример #16
0
 /**
  * Tests the failed search text, and various other text on the search page.
  */
 function testSearchText()
 {
     $this->drupalLogin($this->searchingUser);
     $this->drupalGet('search/node');
     $this->assertText(t('Enter your keywords'));
     $this->assertText(t('Search'));
     $this->assertTitle(t('Search') . ' | Drupal', 'Search page title is correct');
     $edit = array();
     $search_terms = 'bike shed ' . $this->randomMachineName();
     $edit['keys'] = $search_terms;
     $this->drupalPostForm('search/node', $edit, t('Search'));
     $this->assertText('search yielded no results');
     $this->assertText(t('Search'));
     $title_source = 'Search for @keywords | Drupal';
     $this->assertTitle(t($title_source, array('@keywords' => Unicode::truncate($search_terms, 60, TRUE, TRUE))), 'Search page title is correct');
     $this->assertNoText('Node', 'Erroneous tab and breadcrumb text is not present');
     $this->assertNoText(t('Node'), 'Erroneous translated tab and breadcrumb text is not present');
     $this->assertText(t('Content'), 'Tab and breadcrumb text is present');
     $this->clickLink('Search help');
     $this->assertText('Search help', 'Correct title is on search help page');
     $this->assertText('Use upper-case OR to get more results', 'Correct text is on content search help page');
     // Search for a longer text, and see that it is in the title, truncated.
     $edit = array();
     $search_terms = 'Every word is like an unnecessary stain on silence and nothingness.';
     $edit['keys'] = $search_terms;
     $this->drupalPostForm('search/node', $edit, t('Search'));
     $this->assertTitle(t($title_source, array('@keywords' => 'Every word is like an unnecessary stain on silence and…')), 'Search page title is correct');
     // Search for a string with a lot of special characters.
     $search_terms = 'Hear nothing > "see nothing" `feel' . " '1982.";
     $edit['keys'] = $search_terms;
     $this->drupalPostForm('search/node', $edit, t('Search'));
     $actual_title = (string) current($this->xpath('//title'));
     $this->assertEqual($actual_title, String::decodeEntities(t($title_source, array('@keywords' => Unicode::truncate($search_terms, 60, TRUE, TRUE)))), 'Search page title is correct');
     $edit['keys'] = $this->searchingUser->getUsername();
     $this->drupalPostForm('search/user', $edit, t('Search'));
     $this->assertText(t('Search'));
     $this->assertTitle(t($title_source, array('@keywords' => Unicode::truncate($this->searchingUser->getUsername(), 60, TRUE, TRUE))));
     $this->clickLink('Search help');
     $this->assertText('Search help', 'Correct title is on search help page');
     $this->assertText('user names and partial user names', 'Correct text is on user search help page');
     // Test that search keywords containing slashes are correctly loaded
     // from the GET params and displayed in the search form.
     $arg = $this->randomMachineName() . '/' . $this->randomMachineName();
     $this->drupalGet('search/node', array('query' => array('keys' => $arg)));
     $input = $this->xpath("//input[@id='edit-keys' and @value='{$arg}']");
     $this->assertFalse(empty($input), 'Search keys with a / are correctly set as the default value in the search box.');
     // Test a search input exceeding the limit of AND/OR combinations to test
     // the Denial-of-Service protection.
     $limit = $this->config('search.settings')->get('and_or_limit');
     $keys = array();
     for ($i = 0; $i < $limit + 1; $i++) {
         // Use a key of 4 characters to ensure we never generate 'AND' or 'OR'.
         $keys[] = $this->randomMachineName(4);
         if ($i % 2 == 0) {
             $keys[] = 'OR';
         }
     }
     $edit['keys'] = implode(' ', $keys);
     $this->drupalPostForm('search/node', $edit, t('Search'));
     $this->assertRaw(t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', array('@count' => $limit)));
     // Test that a search on Node or User with no keywords entered generates
     // the "Please enter some keywords" message.
     $this->drupalPostForm('search/node', array(), t('Search'));
     $this->assertText(t('Please enter some keywords'), 'With no keywords entered, message is displayed on node page');
     $this->drupalPostForm('search/user', array(), t('Search'));
     $this->assertText(t('Please enter some keywords'), 'With no keywords entered, message is displayed on user page');
     // Make sure the "Please enter some keywords" message is NOT displayed if
     // you use "or" words or phrases in Advanced Search.
     $this->drupalPostForm('search/node', array('or' => $this->randomMachineName() . ' ' . $this->randomMachineName()), t('Advanced search'));
     $this->assertNoText(t('Please enter some keywords'), 'With advanced OR keywords entered, no keywords message is not displayed on node page');
     $this->drupalPostForm('search/node', array('phrase' => '"' . $this->randomMachineName() . '" "' . $this->randomMachineName() . '"'), t('Advanced search'));
     $this->assertNoText(t('Please enter some keywords'), 'With advanced phrase entered, no keywords message is not displayed on node page');
     // Verify that if you search for a too-short keyword, you get the right
     // message, and that if after that you search for a longer keyword, you
     // do not still see the message.
     $this->drupalPostForm('search/node', array('keys' => $this->randomMachineName(1)), t('Search'));
     $this->assertText('You must include at least one positive keyword', 'Keyword message is displayed when searching for short word');
     $this->assertNoText(t('Please enter some keywords'), 'With short word entered, no keywords message is not displayed');
     $this->drupalPostForm(NULL, array('keys' => $this->randomMachineName()), t('Search'));
     $this->assertNoText('You must include at least one positive keyword', 'Keyword message is not displayed when searching for long word after short word search');
     // Test that if you search for a URL with .. in it, you still end up at
     // the search page. See issue https://drupal.org/node/890058.
     $this->drupalPostForm('search/node', array('keys' => '../../admin'), t('Search'));
     $this->assertResponse(200, 'Searching for ../../admin with non-admin user does not lead to a 403 error');
     $this->assertText('no results', 'Searching for ../../admin with non-admin user gives you a no search results page');
     // Test that if you search for a URL starting with "./", you still end up
     // at the search page. See issue https://drupal.org/node/1421560.
     $this->drupalPostForm('search/node', array('keys' => '.something'), t('Search'));
     $this->assertResponse(200, 'Searching for .something does not lead to a 403 error');
     $this->assertText('no results', 'Searching for .something gives you a no search results page');
 }
Пример #17
0
 /**
  * {@inheritdoc}
  */
 public function buildEntity(array $form, FormStateInterface $form_state)
 {
     /** @var \Drupal\comment\CommentInterface $comment */
     $comment = parent::buildEntity($form, $form_state);
     if (!$form_state->isValueEmpty('date') && $form_state->getValue('date') instanceof DrupalDateTime) {
         $comment->setCreatedTime($form_state->getValue('date')->getTimestamp());
     } else {
         $comment->setCreatedTime(REQUEST_TIME);
     }
     $author_name = $form_state->getValue('name');
     if (!$this->currentUser->isAnonymous()) {
         // Assign the owner based on the given user name - none means anonymous.
         $accounts = $this->entityManager->getStorage('user')->loadByProperties(array('name' => $author_name));
         $account = reset($accounts);
         $uid = $account ? $account->id() : 0;
         $comment->setOwnerId($uid);
     }
     // If the comment was posted by an anonymous user and no author name was
     // required, use "Anonymous" by default.
     if ($comment->getOwnerId() === 0 && (!isset($author_name) || $author_name === '')) {
         $comment->setAuthorName($this->config('user.settings')->get('anonymous'));
     }
     // Validate the comment's subject. If not specified, extract from comment
     // body.
     if (trim($comment->getSubject()) == '') {
         // The body may be in any format, so:
         // 1) Filter it into HTML
         // 2) Strip out all HTML tags
         // 3) Convert entities back to plain-text.
         $comment_text = $comment->comment_body->processed;
         $comment->setSubject(Unicode::truncate(trim(String::decodeEntities(strip_tags($comment_text))), 29, TRUE));
         // Edge cases where the comment body is populated only by HTML tags will
         // require a default subject.
         if ($comment->getSubject() == '') {
             $comment->setSubject($this->t('(No subject)'));
         }
     }
     return $comment;
 }