Update to Drupal 8.2.2. For more information, see https://www.drupal.org/project/drupal/releases/8.2.2
This commit is contained in:
parent
23ffed3665
commit
507b45a0ed
378 changed files with 11434 additions and 5542 deletions
|
@ -81,7 +81,7 @@ class Drupal {
|
|||
/**
|
||||
* The current system version.
|
||||
*/
|
||||
const VERSION = '8.2.1';
|
||||
const VERSION = '8.2.2';
|
||||
|
||||
/**
|
||||
* Core API compatibility.
|
||||
|
|
|
@ -288,7 +288,6 @@ class Random {
|
|||
// Make a perfect circle in the image middle.
|
||||
$color = imagecolorallocate($im, rand(0, 255), rand(0, 255), rand(0, 255));
|
||||
$smaller_dimension = min($width, $height);
|
||||
$smaller_dimension = ($smaller_dimension % 2) ? $smaller_dimension : $smaller_dimension;
|
||||
imageellipse($im, $width / 2, $height / 2, $smaller_dimension, $smaller_dimension, $color);
|
||||
|
||||
$save_function = 'image' . ($extension == 'jpg' ? 'jpeg' : $extension);
|
||||
|
|
|
@ -97,12 +97,15 @@ class CsrfRequestHeaderAccessCheck implements AccessCheckInterface {
|
|||
&& $account->isAuthenticated()
|
||||
&& $this->sessionConfiguration->hasSession($request)
|
||||
) {
|
||||
if (!$request->headers->has('X-CSRF-Token')) {
|
||||
return AccessResult::forbidden()->setReason('X-CSRF-Token request header is missing')->setCacheMaxAge(0);
|
||||
}
|
||||
$csrf_token = $request->headers->get('X-CSRF-Token');
|
||||
// @todo Remove validate call using 'rest' in 8.3.
|
||||
// Kept here for sessions active during update.
|
||||
if (!$this->csrfToken->validate($csrf_token, self::TOKEN_KEY)
|
||||
&& !$this->csrfToken->validate($csrf_token, 'rest')) {
|
||||
return AccessResult::forbidden()->setReason('X-CSRF-Token request header is missing')->setCacheMaxAge(0);
|
||||
return AccessResult::forbidden()->setReason('X-CSRF-Token request header is invalid')->setCacheMaxAge(0);
|
||||
}
|
||||
}
|
||||
// Let other access checkers decide if the request is legit.
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Drupal\Core\Ajax;
|
||||
|
||||
use Drupal\Component\Render\PlainTextOutput;
|
||||
|
||||
/**
|
||||
* Defines an AJAX command to open certain content in a dialog.
|
||||
*
|
||||
|
@ -69,6 +71,7 @@ class OpenDialogCommand implements CommandInterface, CommandWithAttachedAssetsIn
|
|||
* populated automatically from the current request.
|
||||
*/
|
||||
public function __construct($selector, $title, $content, array $dialog_options = array(), $settings = NULL) {
|
||||
$title = PlainTextOutput::renderFromHtml($title);
|
||||
$dialog_options += array('title' => $title);
|
||||
$this->selector = $selector;
|
||||
$this->content = $content;
|
||||
|
|
|
@ -214,7 +214,7 @@ class AssetResolver implements AssetResolverInterface {
|
|||
// hook_library_info_alter(). Additionally add the current language to
|
||||
// support translation of JavaScript files via hook_js_alter().
|
||||
$libraries_to_load = $this->getLibrariesToLoad($assets);
|
||||
$cid = 'js:' . $theme_info->getName() . ':' . $this->languageManager->getCurrentLanguage()->getId() . ':' . Crypt::hashBase64(serialize($libraries_to_load) . serialize($assets->getLibraries())) . (int) (count($assets->getSettings()) > 0) . (int) $optimize;
|
||||
$cid = 'js:' . $theme_info->getName() . ':' . $this->languageManager->getCurrentLanguage()->getId() . ':' . Crypt::hashBase64(serialize($libraries_to_load)) . (int) (count($assets->getSettings()) > 0) . (int) $optimize;
|
||||
|
||||
if ($cached = $this->cache->get($cid)) {
|
||||
list($js_assets_header, $js_assets_footer, $settings, $settings_in_header) = $cached->data;
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Drupal\Core\Cache\Context;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
|
||||
/**
|
||||
* Defines the SessionCacheContext service, for "per session" caching.
|
||||
*
|
||||
|
@ -20,7 +22,8 @@ class SessionCacheContext extends RequestStackCacheContextBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getContext() {
|
||||
return $this->requestStack->getCurrentRequest()->getSession()->getId();
|
||||
$sid = $this->requestStack->getCurrentRequest()->getSession()->getId();
|
||||
return Crypt::hashBase64($sid);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ class Schema extends DatabaseSchema {
|
|||
// By default, MySQL uses the default collation for new tables, which is
|
||||
// 'utf8mb4_general_ci' for utf8mb4. If an alternate collation has been
|
||||
// set, it needs to be explicitly specified.
|
||||
// @see DatabaseConnection_mysql
|
||||
// @see \Drupal\Core\Database\Driver\mysql\Schema
|
||||
if (!empty($info['collation'])) {
|
||||
$sql .= ' COLLATE ' . $info['collation'];
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@ class Schema extends DatabaseSchema {
|
|||
/**
|
||||
* A cache of information about blob columns and sequences of tables.
|
||||
*
|
||||
* This is collected by DatabaseConnection_pgsql->queryTableInformation(),
|
||||
* by introspecting the database.
|
||||
* This is collected by Schema::queryTableInformation(), by introspecting the
|
||||
* database.
|
||||
*
|
||||
* @see \Drupal\Core\Database\Driver\pgsql\Schema::queryTableInformation()
|
||||
* @var array
|
||||
|
|
|
@ -306,7 +306,7 @@ class StatementPrefetch implements \Iterator, StatementInterface {
|
|||
return $this->fetchOptions['object'];
|
||||
case \PDO::FETCH_COLUMN:
|
||||
if (isset($this->columnNames[$this->fetchOptions['column']])) {
|
||||
return $this->currentRow[$k][$this->columnNames[$this->fetchOptions['column']]];
|
||||
return $this->currentRow[$this->columnNames[$this->fetchOptions['column']]];
|
||||
}
|
||||
else {
|
||||
return;
|
||||
|
|
|
@ -301,7 +301,7 @@ class EntityController implements ContainerInjectionInterface {
|
|||
* @param array $bundles
|
||||
* An array of bundle information.
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $bundle_entity_type
|
||||
* The ID of the bundle entity type.
|
||||
* The bundle entity type definition.
|
||||
*
|
||||
* @return array
|
||||
* The expanded array of bundle information.
|
||||
|
|
|
@ -236,7 +236,7 @@ class EntityFormDisplay extends EntityDisplayBase implements EntityFormDisplayIn
|
|||
// Flag entity level violations.
|
||||
foreach ($violations->getEntityViolations() as $violation) {
|
||||
/** @var \Symfony\Component\Validator\ConstraintViolationInterface $violation */
|
||||
$form_state->setErrorByName('', $violation->getMessage());
|
||||
$form_state->setError($form, $violation->getMessage());
|
||||
}
|
||||
|
||||
$this->flagWidgetsErrorsFromViolations($violations, $form, $form_state);
|
||||
|
|
|
@ -166,7 +166,10 @@ class EntityResolverManager {
|
|||
list($entity_type) = explode('.', $entity_form, 2);
|
||||
}
|
||||
|
||||
if (isset($entity_type) && isset($this->getEntityTypes()[$entity_type])) {
|
||||
// Do not add parameter information if the route does not declare a
|
||||
// parameter in the first place. This is the case for add forms, for
|
||||
// example.
|
||||
if (isset($entity_type) && isset($this->getEntityTypes()[$entity_type]) && (strpos($route->getPath(), '{' . $entity_type . '}') !== FALSE)) {
|
||||
$parameter_definitions = $route->getOption('parameters') ?: array();
|
||||
|
||||
// First try to figure out whether there is already a parameter upcasting
|
||||
|
|
|
@ -358,11 +358,18 @@ use Drupal\node\Entity\NodeType;
|
|||
* \Drupal\Core\Entity\EntityType.
|
||||
*
|
||||
* @section sec_routes Entity routes
|
||||
* Entity routes, like other routes, are defined in *.routing.yml files; see
|
||||
* the @link routing Routing API @endlink topic for more information. Entities
|
||||
* may alternatively use an auto route provider class; there is an example of
|
||||
* this at the end of this section. If providing routes directly, here is a
|
||||
* typical entry, for the block configure form:
|
||||
* Entity routes can be defined in *.routing.yml files, like any other route:
|
||||
* see the @link routing Routing API @endlink topic for more information.
|
||||
* Another option for entity routes is to use a route provider class, and
|
||||
* reference it in the annotations on the entity class: see the end of this
|
||||
* section for an example.
|
||||
*
|
||||
* It's possible to use both a YAML file and a provider class for entity
|
||||
* routes, at the same time. Avoid duplicating route names between the two:
|
||||
* if a duplicate route name is found in both locations, the one in the YAML
|
||||
* file takes precedence; regardless, such duplication can be confusing.
|
||||
*
|
||||
* Here's an example YAML route specification, for the block configure form:
|
||||
* @code
|
||||
* entity.block.edit_form:
|
||||
* path: '/admin/structure/block/manage/{block}'
|
||||
|
@ -372,7 +379,7 @@ use Drupal\node\Entity\NodeType;
|
|||
* requirements:
|
||||
* _entity_access: 'block.update'
|
||||
* @endcode
|
||||
* Some notes:
|
||||
* Some notes on this example:
|
||||
* - path: The {block} in the path is a placeholder, which (for an entity) must
|
||||
* always take the form of {machine_name_of_entity_type}. In the URL, the
|
||||
* placeholder value will be the ID of an entity item. When the route is used,
|
||||
|
@ -389,19 +396,21 @@ use Drupal\node\Entity\NodeType;
|
|||
* "form" = {
|
||||
* "default" = "Drupal\block\BlockForm",
|
||||
* @endcode
|
||||
* - Instead of putting the routes for your entity in a *.routing.yml file, you
|
||||
* can instead use a route provider class.
|
||||
* \Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider provides canonical,
|
||||
* edit-form, and delete-form routes;
|
||||
* \Drupal\Core\Entity\Routing\AdminHtmlRouteProvider provides the same
|
||||
* If instead of YAML you want to use a route provider class:
|
||||
* - \Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider provides canonical,
|
||||
* edit-form, and delete-form routes.
|
||||
* - \Drupal\Core\Entity\Routing\AdminHtmlRouteProvider provides the same
|
||||
* routes, set up to use the administrative theme for edit and delete pages.
|
||||
* You can also create your own class. To use a route provider class, add
|
||||
* lines like the following to your entity annotation:
|
||||
* @code
|
||||
* handlers = {
|
||||
* "route_provider" = {
|
||||
* "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
|
||||
* @endcode
|
||||
* - You can also create your own class, extending one of these two classes if
|
||||
* you only want to modify their behaviour slightly.
|
||||
*
|
||||
* To register any route provider class, add lines like the following to your
|
||||
* entity class annotation:
|
||||
* @code
|
||||
* handlers = {
|
||||
* "route_provider" = {
|
||||
* "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
|
||||
* @endcode
|
||||
*
|
||||
* @section bundle Defining a content entity bundle
|
||||
* For entity types that use bundles, such as Node (bundles are content types)
|
||||
|
|
|
@ -20,7 +20,7 @@ class PathRootsSubscriber implements EventSubscriberInterface {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $pathRoots;
|
||||
protected $pathRoots = [];
|
||||
|
||||
/**
|
||||
* The state key value store.
|
||||
|
@ -58,7 +58,7 @@ class PathRootsSubscriber implements EventSubscriberInterface {
|
|||
*/
|
||||
public function onRouteFinished() {
|
||||
$this->state->set('router.path_roots', array_keys($this->pathRoots));
|
||||
unset($this->pathRoots);
|
||||
$this->pathRoots = [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,6 +22,8 @@ use Drupal\Core\TypedData\ListInterface;
|
|||
*
|
||||
* When implementing this interface which extends Traversable, make sure to list
|
||||
* IteratorAggregate or Iterator before this interface in the implements clause.
|
||||
*
|
||||
* @see \Drupal\Core\Field\FieldItemInterface
|
||||
*/
|
||||
interface FieldItemListInterface extends ListInterface, AccessibleInterface {
|
||||
|
||||
|
|
|
@ -268,7 +268,26 @@ class EntityReferenceItem extends FieldItemBase implements OptionsProviderInterf
|
|||
*/
|
||||
public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
|
||||
$manager = \Drupal::service('plugin.manager.entity_reference_selection');
|
||||
if ($referenceable = $manager->getSelectionHandler($field_definition)->getReferenceableEntities()) {
|
||||
|
||||
// Instead of calling $manager->getSelectionHandler($field_definition)
|
||||
// replicate the behavior to be able to override the sorting settings.
|
||||
$options = array(
|
||||
'target_type' => $field_definition->getFieldStorageDefinition()->getSetting('target_type'),
|
||||
'handler' => $field_definition->getSetting('handler'),
|
||||
'handler_settings' => $field_definition->getSetting('handler_settings') ?: array(),
|
||||
'entity' => NULL,
|
||||
);
|
||||
|
||||
$entity_type = \Drupal::entityManager()->getDefinition($options['target_type']);
|
||||
$options['handler_settings']['sort'] = [
|
||||
'field' => $entity_type->getKey('id'),
|
||||
'direction' => 'DESC',
|
||||
];
|
||||
$selection_handler = $manager->getInstance($options);
|
||||
|
||||
// Select a random number of references between the last 50 referenceable
|
||||
// entities created.
|
||||
if ($referenceable = $selection_handler->getReferenceableEntities(NULL, 'CONTAINS', 50)) {
|
||||
$group = array_rand($referenceable);
|
||||
$values['target_id'] = array_rand($referenceable[$group]);
|
||||
return $values;
|
||||
|
|
|
@ -87,11 +87,14 @@ class EntityReferenceAutocompleteWidget extends WidgetBase {
|
|||
$entity = $items->getEntity();
|
||||
$referenced_entities = $items->referencedEntities();
|
||||
|
||||
// Append the match operation to the selection settings.
|
||||
$selection_settings = $this->getFieldSetting('handler_settings') + ['match_operator' => $this->getSetting('match_operator')];
|
||||
|
||||
$element += array(
|
||||
'#type' => 'entity_autocomplete',
|
||||
'#target_type' => $this->getFieldSetting('target_type'),
|
||||
'#selection_handler' => $this->getFieldSetting('handler'),
|
||||
'#selection_settings' => $this->getFieldSetting('handler_settings'),
|
||||
'#selection_settings' => $selection_settings,
|
||||
// Entity reference field items are handling validation themselves via
|
||||
// the 'ValidReference' constraint.
|
||||
'#validate_reference' => FALSE,
|
||||
|
|
|
@ -181,8 +181,10 @@ class FileSystem implements FileSystemInterface {
|
|||
// If recursive, create each missing component of the parent directory
|
||||
// individually and set the mode explicitly to override the umask.
|
||||
if ($recursive) {
|
||||
// Ensure the path is using DIRECTORY_SEPARATOR.
|
||||
$uri = str_replace('/', DIRECTORY_SEPARATOR, $uri);
|
||||
// Ensure the path is using DIRECTORY_SEPARATOR, and trim off any trailing
|
||||
// slashes because they can throw off the loop when creating the parent
|
||||
// directories.
|
||||
$uri = rtrim(str_replace('/', DIRECTORY_SEPARATOR, $uri), DIRECTORY_SEPARATOR);
|
||||
// Determine the components of the path.
|
||||
$components = explode(DIRECTORY_SEPARATOR, $uri);
|
||||
// If the filepath is absolute the first component will be empty as there
|
||||
|
|
|
@ -152,7 +152,7 @@ class ExtensionMimeTypeGuesser implements MimeTypeGuesserInterface {
|
|||
129 => 'application/x-iphone',
|
||||
130 => 'application/x-iso9660-image',
|
||||
131 => 'application/x-java-jnlp-file',
|
||||
132 => 'application/x-javascript',
|
||||
132 => 'application/javascript',
|
||||
133 => 'application/x-jmol',
|
||||
134 => 'application/x-kchart',
|
||||
135 => 'application/x-killustrator',
|
||||
|
|
|
@ -316,7 +316,7 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface, FormS
|
|||
// In case the post request exceeds the configured allowed size
|
||||
// (post_max_size), the post request is potentially broken. Add some
|
||||
// protection against that and at the same time have a nice error message.
|
||||
if ($ajax_form_request && !isset($form_state->getUserInput()['form_id'])) {
|
||||
if ($ajax_form_request && !$request->request->has('form_id')) {
|
||||
throw new BrokenPostRequestException($this->getFileUploadMaxSize());
|
||||
}
|
||||
|
||||
|
@ -327,7 +327,9 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface, FormS
|
|||
// then passed through
|
||||
// \Drupal\Core\Form\FormAjaxResponseBuilderInterface::buildResponse() to
|
||||
// build a proper AJAX response.
|
||||
if ($ajax_form_request && $form_state->isProcessingInput()) {
|
||||
// Only do this when the form ID matches, since there is no guarantee from
|
||||
// $ajax_form_request that it's an AJAX request for this particular form.
|
||||
if ($ajax_form_request && $form_state->isProcessingInput() && $request->request->get('form_id') == $form_id) {
|
||||
throw new FormAjaxException($form, $form_state);
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ class Link extends RenderElement {
|
|||
/** @var \Drupal\Core\Utility\LinkGenerator $link_generator */
|
||||
$link_generator = \Drupal::service('link_generator');
|
||||
$generated_link = $link_generator->generate($element['#title'], $element['#url']->setOptions($options));
|
||||
$element['#markup'] = $generated_link->getGeneratedLink();
|
||||
$element['#markup'] = $generated_link;
|
||||
$generated_link->merge(BubbleableMetadata::createFromRenderArray($element))
|
||||
->applyTo($element);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,8 @@ use Drupal\Component\Utility\Html as HtmlUtility;
|
|||
* '#header' => array($this->t('Name'), $this->t('Phone')),
|
||||
* );
|
||||
*
|
||||
* for ($i=1; $i<=4; $i++) {
|
||||
* for ($i = 1; $i <= 4; $i++) {
|
||||
* $form['contacts'][$i]['#attributes'] = array('class' => array('foo', 'baz'));
|
||||
* $form['contacts'][$i]['name'] = array(
|
||||
* '#type' => 'textfield',
|
||||
* '#title' => $this->t('Name'),
|
||||
|
@ -46,6 +47,11 @@ use Drupal\Component\Utility\Html as HtmlUtility;
|
|||
* '#title_display' => 'invisible',
|
||||
* );
|
||||
* }
|
||||
*
|
||||
* $form['contacts'][]['colspan_example'] = array(
|
||||
* '#plain_text' => 'Colspan Example',
|
||||
* '#wrapper_attributes' => array('colspan' => 2, 'class' => array('foo', 'bar')),
|
||||
* );
|
||||
* @endcode
|
||||
* @see \Drupal\Core\Render\Element\Tableselect
|
||||
*
|
||||
|
|
|
@ -42,7 +42,12 @@ class ContentTypeHeaderMatcher implements RouteFilterInterface {
|
|||
// We do not throw a
|
||||
// \Symfony\Component\Routing\Exception\ResourceNotFoundException here
|
||||
// because we don't want to return a 404 status code, but rather a 415.
|
||||
throw new UnsupportedMediaTypeHttpException('No route found that matches "Content-Type: ' . $request->headers->get('Content-Type') . '"');
|
||||
if (!$request->headers->has('Content-Type')) {
|
||||
throw new UnsupportedMediaTypeHttpException('No "Content-Type" request header specified');
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedMediaTypeHttpException('No route found that matches "Content-Type: ' . $request->headers->get('Content-Type') . '"');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -257,7 +257,8 @@ class SessionManager extends NativeSessionStorage implements SessionManagerInter
|
|||
// Unset the session cookies.
|
||||
$session_name = $this->getName();
|
||||
$cookies = $this->requestStack->getCurrentRequest()->cookies;
|
||||
if ($cookies->has($session_name)) {
|
||||
// setcookie() can only be called when headers are not yet sent.
|
||||
if ($cookies->has($session_name) && !headers_sent()) {
|
||||
$params = session_get_cookie_params();
|
||||
setcookie($session_name, '', REQUEST_TIME - 3600, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
|
||||
$cookies->remove($session_name);
|
||||
|
|
|
@ -8,6 +8,7 @@ use Drupal\Core\Cache\CacheableDependencyInterface;
|
|||
use Drupal\Core\Datetime\DateFormatterInterface;
|
||||
use Drupal\Core\Render\AttachmentsInterface;
|
||||
use Drupal\Core\Render\BubbleableMetadata;
|
||||
use Drupal\Core\Render\Markup;
|
||||
use Drupal\Core\Render\RenderableInterface;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\Core\Routing\UrlGeneratorInterface;
|
||||
|
@ -273,6 +274,11 @@ class TwigExtension extends \Twig_Extension {
|
|||
}
|
||||
$url->setOption('attributes', $attributes);
|
||||
}
|
||||
// The text has been processed by twig already, convert it to a safe object
|
||||
// for the render system.
|
||||
if ($text instanceof \Twig_Markup) {
|
||||
$text = Markup::create($text);
|
||||
}
|
||||
$build = [
|
||||
'#type' => 'link',
|
||||
'#title' => $text,
|
||||
|
|
63
core/lib/Drupal/Core/Test/TestStatus.php
Normal file
63
core/lib/Drupal/Core/Test/TestStatus.php
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Test;
|
||||
|
||||
/**
|
||||
* Consolidates test result status information.
|
||||
*
|
||||
* For our test runners, a $status of 0 = passed test, 1 = failed test,
|
||||
* 2 = exception, >2 indicates segfault timeout, or other type of system
|
||||
* failure.
|
||||
*/
|
||||
class TestStatus {
|
||||
|
||||
/**
|
||||
* Signify that the test result was a passed test.
|
||||
*/
|
||||
const PASS = 0;
|
||||
|
||||
/**
|
||||
* Signify that the test result was a failed test.
|
||||
*/
|
||||
const FAIL = 1;
|
||||
|
||||
/**
|
||||
* Signify that the test result was an exception or code error.
|
||||
*
|
||||
* This means that the test runner was able to exit and report an error.
|
||||
*/
|
||||
const EXCEPTION = 2;
|
||||
|
||||
/**
|
||||
* Signify a system error where the test runner was unable to complete.
|
||||
*
|
||||
* Note that SYSTEM actually represents the lowest value of system errors, and
|
||||
* the returned value could be as high as 127. Since that's the case, this
|
||||
* constant should be used for range comparisons, and not just for equality.
|
||||
*
|
||||
* @see http://php.net/manual/en/pcntl.constants.php
|
||||
*/
|
||||
const SYSTEM = 3;
|
||||
|
||||
/**
|
||||
* Turns a status code into a human-readable string.
|
||||
*
|
||||
* @param int $status
|
||||
* A test runner return code.
|
||||
*
|
||||
* @return string
|
||||
* The human-readable version of the status code.
|
||||
*/
|
||||
public static function label($status) {
|
||||
$statusMap = [
|
||||
static::PASS => 'pass',
|
||||
static::FAIL => 'fail',
|
||||
static::EXCEPTION => 'exception',
|
||||
static::SYSTEM => 'error',
|
||||
];
|
||||
// For status 3 and higher, we want 'error.'
|
||||
$label = $statusMap[$status > static::SYSTEM ? static::SYSTEM : $status];
|
||||
return $label;
|
||||
}
|
||||
|
||||
}
|
|
@ -31,7 +31,7 @@ interface LinkGeneratorInterface {
|
|||
* This keeps the context of the link title ('settings' in the example) for
|
||||
* translators.
|
||||
*
|
||||
* @param string|array $text
|
||||
* @param string|array|\Drupal\Component\Render\MarkupInterface $text
|
||||
* The link text for the anchor tag as a translated string or render array.
|
||||
* Strings will be sanitized automatically. If you need to output HTML in
|
||||
* the link text, use a render array or an already sanitized string such as
|
||||
|
|
Reference in a new issue