You are here

public function DoTrustedCallbackTrait::doTrustedCallback in Drupal 9

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php \Drupal\Core\Security\DoTrustedCallbackTrait::doTrustedCallback()

Performs a callback.

If the callback is trusted the callback will occur. Trusted callbacks must 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.

Parameters

callable $callback: The callback to call. Note that callbacks which are objects and use the magic method __invoke() are not supported.

array $args: The arguments to pass the callback.

$message: The error message if the callback is not trusted. If the message contains "%s" it will be replaced in with the resolved callback.

string $error_type: (optional) The type of error to trigger. One of:

Defaults to TrustedCallbackInterface::THROW_EXCEPTION.

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 value

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 also

\Drupal\Core\Security\TrustedCallbackInterface

6 calls to DoTrustedCallbackTrait::doTrustedCallback()
DoTrustedCallbackTraitTest::testException in core/tests/Drupal/Tests/Core/Security/DoTrustedCallbackTraitTest.php
@dataProvider errorTypeProvider
DoTrustedCallbackTraitTest::testSilencedDeprecation in core/tests/Drupal/Tests/Core/Security/DoTrustedCallbackTraitTest.php
@dataProvider errorTypeProvider @group legacy
DoTrustedCallbackTraitTest::testTrustedCallbacks in core/tests/Drupal/Tests/Core/Security/DoTrustedCallbackTraitTest.php
@covers ::doTrustedCallback @dataProvider providerTestTrustedCallbacks
DoTrustedCallbackTraitTest::testUntrustedCallbacks in core/tests/Drupal/Tests/Core/Security/DoTrustedCallbackTraitTest.php
@covers ::doTrustedCallback @dataProvider providerTestUntrustedCallbacks
DoTrustedCallbackTraitTest::testWarning in core/tests/Drupal/Tests/Core/Security/DoTrustedCallbackTraitTest.php
@dataProvider errorTypeProvider

... See full list

File

core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php, line 51

Class

DoTrustedCallbackTrait
Ensures that TrustedCallbackInterface can be enforced for callback methods.

Namespace

Drupal\Core\Security

Code

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)) {
    list($object_or_classname, $method_name) = $callback;
  }
  elseif (is_string($callback) && strpos($callback, '::') !== FALSE) {
    list($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);
    }
  }
  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($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));
}