trait DoTrustedCallbackTrait
Same name in other branches
- 9 core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php \Drupal\Core\Security\DoTrustedCallbackTrait
- 8.9.x core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php \Drupal\Core\Security\DoTrustedCallbackTrait
- 11.x core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php \Drupal\Core\Security\DoTrustedCallbackTrait
Ensures that only predefined methods can be used as callback methods.
Hierarchy
- trait \Drupal\Core\Security\DoTrustedCallbackTrait
See also
\Drupal\Core\Security\Attribute\TrustedCallback
\Drupal\Core\Security\TrustedCallbackInterface
6 files declare their use of DoTrustedCallbackTrait
- ComponentElement.php in core/
modules/ sdc/ src/ Element/ ComponentElement.php - ComponentElement.php in core/
lib/ Drupal/ Core/ Render/ Element/ ComponentElement.php - Datelist.php in core/
lib/ Drupal/ Core/ Datetime/ Element/ Datelist.php - Datetime.php in core/
lib/ Drupal/ Core/ Datetime/ Element/ Datetime.php - DoTrustedCallbackTraitTest.php in core/
tests/ Drupal/ Tests/ Core/ Security/ DoTrustedCallbackTraitTest.php
File
-
core/
lib/ Drupal/ Core/ Security/ DoTrustedCallbackTrait.php, line 13
Namespace
Drupal\Core\SecurityView source
trait DoTrustedCallbackTrait {
/**
* Performs a callback.
*
* If the callback is trusted the callback will occur. Trusted callbacks must
* be methods that are tagged with the
* \Drupal\Core\Security\Attribute\TrustedCallback attribute, or be methods of
* a class that implements
* \Drupal\Core\Security\TrustedCallbackInterface or $extra_trusted_interface,
* or be an anonymous function. If the callback is not trusted then whether or
* not the callback is called and what type of error is thrown depends on
* $error_type. To provide time for dependent code to use trusted callbacks
* use TrustedCallbackInterface::TRIGGER_SILENCED_DEPRECATION and then at a
* later date change this to TrustedCallbackInterface::THROW_EXCEPTION.
*
* @param callable $callback
* The callback to call. Note that callbacks which are objects and use the
* magic method __invoke() are not supported.
* @param array $args
* The arguments to pass the callback.
* @param $message
* The error message if the callback is not trusted. If the message contains
* "%s" it will be replaced in with the resolved callback.
* @param string $error_type
* (optional) The type of error to trigger. One of:
* - TrustedCallbackInterface::THROW_EXCEPTION
* - (deprecated) TrustedCallbackInterface::TRIGGER_WARNING
* - TrustedCallbackInterface::TRIGGER_SILENCED_DEPRECATION
* Defaults to TrustedCallbackInterface::THROW_EXCEPTION.
* @param string $extra_trusted_interface
* (optional) An additional interface that if implemented by the callback
* object means any public methods on that object are trusted.
*
* @return mixed
* The callback's return value.
*
* @throws \Drupal\Core\Security\UntrustedCallbackException
* Exception thrown if the callback is not trusted and $error_type equals
* TrustedCallbackInterface::THROW_EXCEPTION.
*
* @see \Drupal\Core\Security\Attribute\TrustedCallback
* @see \Drupal\Core\Security\TrustedCallbackInterface
*/
public function doTrustedCallback(callable $callback, array $args, $message, $error_type = TrustedCallbackInterface::THROW_EXCEPTION, $extra_trusted_interface = NULL) {
$object_or_classname = $callback;
$safe_callback = FALSE;
if (is_array($callback)) {
[
$object_or_classname,
$method_name,
] = $callback;
}
elseif (is_string($callback) && str_contains($callback, '::')) {
[
$object_or_classname,
$method_name,
] = explode('::', $callback, 2);
}
if (isset($method_name)) {
if ($extra_trusted_interface && is_subclass_of($object_or_classname, $extra_trusted_interface)) {
$safe_callback = TRUE;
}
elseif (is_subclass_of($object_or_classname, TrustedCallbackInterface::class)) {
if (is_object($object_or_classname)) {
$methods = $object_or_classname->trustedCallbacks();
}
else {
$methods = call_user_func($object_or_classname . '::trustedCallbacks');
}
$safe_callback = in_array($method_name, $methods, TRUE);
}
if (!$safe_callback) {
$method = new \ReflectionMethod($object_or_classname, $method_name);
$safe_callback = (bool) $method->getAttributes(TrustedCallback::class);
}
}
elseif ($callback instanceof \Closure) {
$safe_callback = TRUE;
}
if (!$safe_callback) {
$description = $object_or_classname;
if (is_object($description)) {
$description = get_class($description);
}
if (isset($method_name)) {
$description .= '::' . $method_name;
}
$message = sprintf($message, $description);
if ($error_type === TrustedCallbackInterface::TRIGGER_SILENCED_DEPRECATION) {
@trigger_error($message, E_USER_DEPRECATED);
}
elseif ($error_type === TrustedCallbackInterface::TRIGGER_WARNING) {
@trigger_error('Passing E_USER_WARNING for $error_type in ' . __METHOD__ . '() is deprecated in drupal:10.3.0 and will be removed from drupal:11.0.0. Use TrustedCallbackInterface::THROW_EXCEPTION or TrustedCallbackInterface::TRIGGER_SILENCED_DEPRECATION instead. See https://www.drupal.org/node/3427367', E_USER_DEPRECATED);
trigger_error($message, E_USER_WARNING);
}
else {
throw new UntrustedCallbackException($message);
}
}
// @todo Allow named arguments in https://www.drupal.org/node/3174150
return call_user_func_array($callback, array_values($args));
}
}
Members
Title Sort descending | Modifiers | Object type | Summary |
---|---|---|---|
DoTrustedCallbackTrait::doTrustedCallback | public | function | Performs a callback. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.