class RestUIController in REST UI 8
Controller routines for REST resources.
Hierarchy
- class \Drupal\restui\Controller\RestUIController implements ContainerInjectionInterface uses StringTranslationTrait
Expanded class hierarchy of RestUIController
File
- src/
Controller/ RestUIController.php, line 19
Namespace
Drupal\restui\ControllerView source
class RestUIController implements ContainerInjectionInterface {
use StringTranslationTrait;
/**
* Resource plugin manager.
*
* @var \Drupal\rest\Plugin\Type\ResourcePluginManager
*/
protected $resourcePluginManager;
/**
* The URL generator to use.
*
* @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface
*/
protected $urlGenerator;
/**
* Configuration entity to store enabled REST resources.
*
* @var \Drupal\rest\RestResourceConfigInterface
*/
protected $resourceConfigStorage;
/**
* The messenger service.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* Injects RestUIManager Service.
*/
public static function create(ContainerInterface $container) {
return new static($container
->get('plugin.manager.rest'), $container
->get('url_generator'), $container
->get('entity_type.manager')
->getStorage('rest_resource_config'), $container
->get('messenger'));
}
/**
* Constructs a RestUIController object.
*
* @param \Drupal\rest\Plugin\Type\ResourcePluginManager $resourcePluginManager
* The REST resource plugin manager.
* @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface $url_generator
* The URL generator.
* @param \Drupal\Core\Entity\EntityStorageInterface $resource_config_storage
* The REST resource config storage.
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* The messenger service.
*/
public function __construct(ResourcePluginManager $resourcePluginManager, UrlGeneratorInterface $url_generator, EntityStorageInterface $resource_config_storage, MessengerInterface $messenger) {
$this->resourcePluginManager = $resourcePluginManager;
$this->urlGenerator = $url_generator;
$this->resourceConfigStorage = $resource_config_storage;
$this->messenger = $messenger;
}
/**
* Returns an administrative overview of all REST resources.
*
* @return string
* A HTML-formatted string with the administrative page content.
*/
public function listResources() {
// Get the list of enabled and disabled resources.
$config = $this->resourceConfigStorage
->loadMultiple();
// Strip out the nested method configuration, we are only interested in the
// plugin IDs of the resources.
$enabled_resources = array_combine(array_keys($config), array_keys($config));
$available_resources = [
'enabled' => [],
'disabled' => [],
];
$resources = $this->resourcePluginManager
->getDefinitions();
foreach ($resources as $id => $resource) {
$key = $this
->getResourceKey($id);
$status = in_array($key, $enabled_resources) && $config[$key]
->status() ? 'enabled' : 'disabled';
$available_resources[$status][$id] = $resource;
}
// Sort the list of resources by label.
$sort_resources = function ($resource_a, $resource_b) {
return strcmp($resource_a['label'], $resource_b['label']);
};
if (!empty($available_resources['enabled'])) {
uasort($available_resources['enabled'], $sort_resources);
}
if (!empty($available_resources['disabled'])) {
uasort($available_resources['disabled'], $sort_resources);
}
$list['enabled']['heading']['#markup'] = '<h2>' . $this
->t('Enabled') . '</h2>';
$list['disabled']['heading']['#markup'] = '<h2>' . $this
->t('Disabled') . '</h2>';
// List of resources.
foreach ([
'enabled',
'disabled',
] as $status) {
$list[$status]['#type'] = 'container';
$list[$status]['#attributes'] = [
'class' => [
'rest-ui-list-section',
$status,
],
];
$list[$status]['table'] = [
'#theme' => 'table',
'#header' => [
'resource_name' => [
'data' => $this
->t('Resource name'),
'class' => [
'rest-ui-name',
],
],
'path' => [
'data' => $this
->t('Path'),
'class' => [
'views-ui-path',
],
],
'description' => [
'data' => $this
->t('Description'),
'class' => [
'rest-ui-description',
],
],
'operations' => [
'data' => $this
->t('Operations'),
'class' => [
'rest-ui-operations',
],
],
],
'#rows' => [],
];
foreach ($available_resources[$status] as $id => $resource) {
$canonical_uri_path = !empty($resource['uri_paths']['canonical']) ? $resource['uri_paths']['canonical'] : FALSE;
// @see https://www.drupal.org/node/2737401
// @todo Remove this in Drupal 9.0.0.
$old_create_uri_path = !empty($resource['uri_paths']['https://www.drupal.org/link-relations/create']) ? $resource['uri_paths']['https://www.drupal.org/link-relations/create'] : FALSE;
$new_create_uri_path = !empty($resource['uri_paths']['create']) ? $resource['uri_paths']['create'] : FALSE;
$create_uri_path = $new_create_uri_path ?: $old_create_uri_path;
$available_methods = array_intersect(array_map('strtoupper', get_class_methods($resource['class'])), [
'HEAD',
'GET',
'POST',
'PUT',
'DELETE',
'TRACE',
'OPTIONS',
'CONNECT',
'PATCH',
]);
// @todo Remove this when https://www.drupal.org/node/2300677 is fixed.
$is_config_entity = isset($resource['serialization_class']) && is_subclass_of($resource['serialization_class'], ConfigEntityInterface::class, TRUE);
if ($is_config_entity) {
$available_methods = array_diff($available_methods, [
'POST',
'PATCH',
'DELETE',
]);
$create_uri_path = FALSE;
}
// Now calculate the configured methods: if a RestResourceConfig entity
// exists for this @RestResource plugin, then regardless of whether that
// configuration is enabled or not, inspect its enabled methods. Strike
// through all disabled methods, so that it's clearly conveyed in the UI
// which methods are supported on which URL, but may be disabled.
if (isset($config[$this
->getResourceKey($id)])) {
$enabled_methods = $config[$this
->getResourceKey($id)]
->getMethods();
$disabled_methods = array_diff($available_methods, $enabled_methods);
$configured_methods = array_merge(array_intersect($available_methods, $enabled_methods), array_map(function ($method) {
return "<del>{$method}</del>";
}, $disabled_methods));
if (!in_array('POST', $enabled_methods)) {
$create_uri_path = FALSE;
}
}
else {
$configured_methods = $available_methods;
}
// All necessary information is collected, now generate some HTML.
$canonical_methods = implode(', ', array_diff($configured_methods, [
'POST',
]));
if ($canonical_uri_path && $create_uri_path) {
$uri_paths = "<code>{$canonical_uri_path}</code>: {$canonical_methods}";
$uri_paths .= "</br><code>{$create_uri_path}</code>: POST";
}
else {
if ($canonical_uri_path) {
$uri_paths = "<code>{$canonical_uri_path}</code>: {$canonical_methods}";
}
else {
$uri_paths = "<code>{$create_uri_path}</code>: POST";
}
}
$list[$status]['table']['#rows'][$id] = [
'data' => [
'name' => !$is_config_entity ? $resource['label'] : $this
->t('@label <sup>(read-only)</sup>', [
'@label' => $resource['label'],
]),
'path' => [
'data' => [
'#type' => 'inline_template',
'#template' => $uri_paths,
],
],
'description' => [],
'operations' => [],
],
];
if ($status == 'disabled') {
$list[$status]['table']['#rows'][$id]['data']['operations']['data'] = [
'#type' => 'operations',
'#links' => [
'enable' => [
'title' => $this
->t('Enable'),
'url' => Url::fromRoute('restui.edit', [
'resource_id' => $id,
]),
],
],
];
}
else {
$list[$status]['table']['#rows'][$id]['data']['operations']['data'] = [
'#type' => 'operations',
'#links' => [
'edit' => [
'title' => $this
->t('Edit'),
'url' => Url::fromRoute('restui.edit', [
'resource_id' => $id,
]),
],
'disable' => [
'title' => $this
->t('Disable'),
'url' => Url::fromRoute('restui.disable', [
'resource_id' => $id,
]),
],
'permissions' => [
'title' => $this
->t('Permissions'),
'url' => Url::fromRoute('user.admin_permissions', [], [
'fragment' => 'module-rest',
]),
],
],
];
$list[$status]['table']['#rows'][$id]['data']['description']['data'] = [
'#theme' => 'restui_resource_info',
'#granularity' => $config[$this
->getResourceKey($id)]
->get('granularity'),
'#configuration' => $config[$this
->getResourceKey($id)]
->get('configuration'),
];
}
}
}
$list['enabled']['table']['#empty'] = $this
->t('There are no enabled resources.');
$list['disabled']['table']['#empty'] = $this
->t('There are no disabled resources.');
$list['#title'] = $this
->t('REST resources');
return $list;
}
/**
* Disables a resource.
*
* @param string $resource_id
* The identifier or the REST resource.
*
* @return \Drupal\Core\Ajax\AjaxResponse|\Symfony\Component\HttpFoundation\RedirectResponse
* Redirects back to the listing page.
*
* @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
* Access is denied, if the token is invalid or missing.
*/
public function disable($resource_id) {
$resources = $this->resourceConfigStorage
->loadMultiple();
if ($resources[$this
->getResourceKey($resource_id)]) {
$resources[$this
->getResourceKey($resource_id)]
->disable()
->save();
$this->messenger
->addStatus($this
->t('The resource was disabled successfully.'));
}
// Redirect back to the page.
return new RedirectResponse($this->urlGenerator
->generate('restui.list', [], TRUE));
}
/**
* The key used in the form.
*
* @param string $resource_id
* The resource ID.
*
* @return string
* The resource key in the form.
*/
protected function getResourceKey($resource_id) {
return str_replace(':', '.', $resource_id);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
RestUIController:: |
protected | property | The messenger service. | |
RestUIController:: |
protected | property | Configuration entity to store enabled REST resources. | |
RestUIController:: |
protected | property | Resource plugin manager. | |
RestUIController:: |
protected | property | The URL generator to use. | |
RestUIController:: |
public static | function |
Injects RestUIManager Service. Overrides ContainerInjectionInterface:: |
|
RestUIController:: |
public | function | Disables a resource. | |
RestUIController:: |
protected | function | The key used in the form. | |
RestUIController:: |
public | function | Returns an administrative overview of all REST resources. | |
RestUIController:: |
public | function | Constructs a RestUIController object. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |