View source
<?php
namespace Drupal\js\Plugin\Js;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Plugin\PluginBase;
use Drupal\js\JsResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route;
abstract class JsCallbackBase extends PluginBase implements JsCallbackInterface {
protected $classResolver;
protected $js;
protected $response;
protected $parameters;
protected $paramConversion;
protected $title;
public function __construct(array $configuration, $plugin_id, $plugin_definition) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->classResolver = \Drupal::service('class_resolver');
$this->js = \Drupal::service('js.callback');
$this->paramConversion = \Drupal::service('route_enhancer.param_conversion');
$this->title = isset($this->pluginDefinition['title']) ? $this->pluginDefinition['title'] : '';
try {
$this->response = $this->classResolver
->getInstanceFromDefinition($this->pluginDefinition['response']);
} catch (\Exception $e) {
}
if (!$this->response instanceof JsResponse) {
throw new \InvalidArgumentException('JS Callback requires that the "response" option be either a service identifier or a class name creating an instance that is or inherits from \\Drupal\\js\\JsResponse.');
}
$this->parameters = $this
->convertParameters();
}
public function access() {
return TRUE;
}
public function accessDeniedMessage() {
return $this
->t('Unauthorized access. If you feel this is in error, please contact the site administrator.');
}
public function anonymousUserMessage() {
return $this
->t('Cannot complete request: requires authentication. Try refreshing this page or logging out and back in again.');
}
public function call($method) {
return call_user_func_array([
$this,
$method,
], $this
->mapMethodParameters($method));
}
public function captureOutput() {
return !!$this->pluginDefinition['capture_output'];
}
protected function convertParameters() {
if (!$this->js
->isExecuting()) {
return [];
}
$request = $this->js
->getRequest();
$parameters = $request->query
->all() + $request->request
->all();
if ($this->pluginDefinition['parameters']) {
$options = [
'parameters' => $this->pluginDefinition['parameters'],
];
$route = new Route('/{' . implode('}/{', array_keys($parameters)) . '}', $parameters, [], $options);
$parameters = $this->paramConversion
->enhance([
'_route_object' => $route,
] + $parameters, Request::create(''));
unset($parameters['_route_object']);
unset($parameters['_raw_variables']);
$boolean_values = [
'true',
'false',
'1',
'0',
'yes',
'no',
];
foreach ($parameters as $key => $value) {
if (is_string($value) && $value !== '' && ($value[0] === '[' || $value[0] === '{') && ($json = Json::decode($value))) {
$parameters[$key] = $json;
}
elseif (is_string($value) && in_array($value, $boolean_values)) {
$parameters[$key] = (bool) $value;
}
}
}
return $parameters;
}
public function csrfToken() {
return !!$this->pluginDefinition['csrf_token'];
}
public function getAllowedMethods() {
return $this->pluginDefinition['allowed_methods'];
}
public function invalidTokenMessage() {
return $this
->t('Cannot complete request: invalid CSRF token. Try refreshing this page or logging out and back in again.');
}
public function mapMethodParameters($method) {
$args = [];
$parameters = $this
->getParameters();
$reflection = new \ReflectionClass($this);
$function = $reflection
->getMethod($method);
foreach ($function
->getParameters() as $param) {
$default_value = $param
->isDefaultValueAvailable() ? $param
->getDefaultValue() : NULL;
$value = isset($parameters[$param->name]) ? $parameters[$param->name] : $default_value;
if (isset($value) && !is_object($value) && ($type = gettype($default_value))) {
settype($value, $type);
}
$args[$param->name] = $value;
}
return $args;
}
public function getParameters() {
return $this->parameters;
}
public function getResponse() {
return $this->response;
}
public function getTitle() {
return $this->title;
}
public function setTitle($title = '') {
$this->title = $title;
}
public function methodNotAllowedMessage() {
$allowed = $this
->getAllowedMethods();
return $this
->formatPlural(count($allowed), 'Method not allowed: %method. Only the %allowed_methods method is allowed. Please contact the site administrator if this problem persists.', 'Method not allowed: %method. Only the %allowed_methods methods are allowed. Please contact the site administrator if this problem persists.', [
'%method' => $this->js
->getRequest()
->getMethod(),
'%allowed_methods' => implode(', ', $allowed),
]);
}
public function validate() {
return TRUE;
}
}