/**
  * Tests a YAML file containing both static permissions and a callback.
  */
 public function testPermissionsYamlStaticAndCallback()
 {
     vfsStreamWrapper::register();
     $root = new vfsStreamDirectory('modules');
     vfsStreamWrapper::setRoot($root);
     $this->moduleHandler = $this->getMock('Drupal\\Core\\Extension\\ModuleHandlerInterface');
     $this->moduleHandler->expects($this->once())->method('getModuleDirectories')->willReturn(array('module_a' => vfsStream::url('modules/module_a')));
     $url = vfsStream::url('modules');
     mkdir($url . '/module_a');
     file_put_contents($url . '/module_a/module_a.permissions.yml', "'access module a':\n  title: 'Access A'\n  description: 'bla bla'\npermission_callbacks:\n  - 'Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescription'\n");
     $modules = array('module_a');
     $extensions = array('module_a' => $this->mockModuleExtension('module_a', 'Module a'));
     $this->moduleHandler->expects($this->any())->method('getImplementations')->with('permission')->willReturn(array());
     $this->moduleHandler->expects($this->any())->method('getModuleList')->willReturn(array_flip($modules));
     $this->controllerResolver->expects($this->once())->method('getControllerFromDefinition')->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescription')->willReturn(array(new TestPermissionCallbacks(), 'titleDescription'));
     $this->permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver);
     // Setup system_rebuild_module_data().
     $this->permissionHandler->setSystemRebuildModuleData($extensions);
     $actual_permissions = $this->permissionHandler->getPermissions();
     $this->assertCount(2, $actual_permissions);
     $this->assertEquals($actual_permissions['access module a']['title'], 'Access A');
     $this->assertEquals($actual_permissions['access module a']['provider'], 'module_a');
     $this->assertEquals($actual_permissions['access module a']['description'], 'bla bla');
     $this->assertEquals($actual_permissions['access module b']['title'], 'Access B');
     $this->assertEquals($actual_permissions['access module b']['provider'], 'module_a');
     $this->assertEquals($actual_permissions['access module b']['description'], 'bla bla');
 }
 /**
  * {@inheritdoc}
  */
 public function form(array $form, FormStateInterface $form_state)
 {
     $form = parent::form($form, $form_state);
     /* @var \Drupal\simple_oauth\AccessTokenResourceInterface $access_token_resource */
     $access_token_resource = $this->entity;
     $form['label'] = array('#type' => 'textfield', '#title' => $this->t('Label'), '#maxlength' => 255, '#default_value' => $access_token_resource->label(), '#description' => $this->t('Label for the Access Token Resource.'), '#required' => TRUE);
     $form['description'] = array('#type' => 'textarea', '#title' => $this->t('Description'), '#default_value' => $access_token_resource->getDescription(), '#description' => $this->t('Description for the Access Token Resource.'), '#required' => FALSE);
     $form['id'] = array('#type' => 'machine_name', '#default_value' => $access_token_resource->id(), '#machine_name' => array('exists' => '\\Drupal\\simple_oauth\\Entity\\AccessTokenResource::load'), '#disabled' => !$access_token_resource->isNew());
     $permissions_list = [];
     $ph = new PermissionHandler($this->moduleHandler, $this->stringTranslation, \Drupal::service('controller_resolver'));
     foreach ($ph->getPermissions() as $permission => $permission_info) {
         $permissions_list[$permission] = $permission_info['title'];
     }
     $form['permissions'] = array('#type' => 'checkboxes', '#title' => $this->t('Permissions'), '#default_value' => $access_token_resource->get('permissions'), '#description' => $this->t('A collection of permissions around a given feature. If a user is authenticated with a token that grants access to this scope, that user will ony be granted access (at most) to the permissions in this list. This will not grant access to any permissions forbidden to the user by their roles.'), '#options' => $permissions_list, '#required' => TRUE, '#attached' => ['library' => ['simple_oauth/drupal.access_token']]);
     return $form;
 }
  /**
   * Controller callback for route detail.
   */
  public function routeDetail($path) {
    $path = str_replace('::', '/', $path);
    $theme_key = str_replace(array('/', '{', '}'), array('__', '', ''), $path);
    $routes = $this->routeProvider->getRoutesByPattern($path)->all();
    $return = array(
      'overview' => array(
        '#theme' => 'rest_api_doc_detail__' . $theme_key,
        '#path' => $path,
        '#title' => $path,
      ),
    );
    $first = TRUE;
    foreach ($routes as $route_name => $route) {
      if (!in_array($route_name, $this->config->get('routes'))) {
        continue;
      }
      $return[$route_name] = array(
        '#type' => 'details',
        '#title' => $path . ' (' . implode(', ', $route->getMethods()) . ' )',
        '#open' => $first,
      );
      $first = FALSE;
      $controller = $route->getDefault('_controller');
      if (strpos($controller, '::') !== FALSE) {
        list($controller_class, $controller_method) = explode('::', $controller);
        $reflection = new \ReflectionMethod($controller_class, $controller_method);
        if ($php_doc = $this->parseMethodDocBlock($reflection)) {
          $return[$route_name]['summary'] = array(
            '#markup' => Xss::filterAdmin($php_doc),
          );
        }
      }
      $auth = array();
      if ($route->getRequirement('_access_rest_csrf')) {
        $auth['CSRF token'] = $this->t('CSRF token: REQUIRED');
      }
      if ($authentication_methods = $route->getOption('_auth')) {
        $auth += $authentication_methods;
      }
      $return[$route_name]['auth'] = array(
        '#theme' => 'item_list',
        '#items' => $auth,
        '#title' => $this->t('Authentication methods'),
      );
      if ($formats = $route->getRequirement('_format')) {
        $return[$route_name]['formats'] = array(
          '#theme' => 'item_list',
          '#items' => explode('|', $formats),
          '#title' => $this->t('Supported formats'),
        );
      }
      if ($permission = $route->getRequirement('_permission')) {
        if (empty($this->permissions)) {
          $this->permissions = $this->permissionHandler->getPermissions();
        }
        if (!empty($this->permissions[$permission])) {
          $return[$route_name]['permisisons'] = array(
            '#theme' => 'item_list',
            '#items' => array($this->permissions[$permission]['title']),
            '#title' => $this->t('Required permissions'),
          );
        }
      }

      if ($parameters = $route->getOption('parameters')) {
        $return[$route_name]['requirements'] = array(
          '#theme' => 'table',
          '#rows' => array(),
          '#caption' => $this->t('Requirements'),
          '#header' => array(
            $this->t('Name'),
            $this->t('Type'),
            $this->t('Required'),
          ),
        );
        foreach ($parameters as $name => $detail) {
          $type = $detail['type'];
          if (strpos($type, 'entity:') === FALSE) {
            // We only handle entity parameters from here onwards.
            continue;
          }
          list(, $entity_type_id) = explode(':', $type);
          $entity_type = $this->entityManager()->getDefinition($entity_type_id);
          $id_field_name = $entity_type->getKey('id');
          $base_fields = $this->entityManager()->getBaseFieldDefinitions($entity_type_id);
          $id_field = $base_fields[$id_field_name];
          $row = array(
            $name,
            $id_field->getType(),
            'TRUE',
          );
          $return[$route_name]['requirements']['#rows'][] = $row;

          if ($route->getMethods() == array('DELETE') || $route->getMethods() == array('GET')) {
            // No body for these two verbs.
            continue;
          }
          $return[$route_name]['detail'] = array(
            '#theme' => 'table',
            '#rows' => array(),
            '#empty' => $this->t('No parameters found'),
            '#caption' => $this->t('Parameters'),
            '#header' => array(
              $this->t('Name'),
              $this->t('Type'),
              $this->t('Required'),
              $this->t('Description'),
            ),
          );
          foreach ($base_fields as $field_name => $field) {
            $row = array(
              $field_name,
              $field->getType(),
              $field->isRequired() ? 'TRUE' : 'FALSE',
              $field->getDescription(),
            );
            $return[$route_name]['detail']['#rows'][] = $row;
          }
          $bundle_info = $this->entityManager()->getBundleInfo($entity_type_id);
          if (count($bundle_info) > 1) {
            // Multiple bundles.
            foreach (array_keys($bundle_info) as $bundle) {
              $label = $bundle_info[$bundle]['label'];
              $row = array(
                'cells' => array(
                  'colspan' => 4,
                  'data' => $this->t('Fields available for @label (@bundle_key = @bundle)', array(
                      '@label' => $label,
                      '@bundle_key' => $entity_type->getKey('bundle'),
                      '@bundle' => $bundle,
                    )
                  ),
                  'header' => TRUE,
                ),
              );
              $return[$route_name]['detail']['#rows'][] = $row;
              $field_definitions = $this->entityManager()->getFieldDefinitions($entity_type_id, $bundle);
              foreach ($field_definitions as $field_name => $field) {
                if (!empty($base_fields[$field_name])) {
                  continue;
                }
                $row = array(
                  $field_name,
                  $field->getType(),
                  $field->isRequired() ? 'TRUE' : 'FALSE',
                  $field->getDescription(),
                );
                $return[$route_name]['detail']['#rows'][] = $row;
              }
            }
          }
          else {
            // Single bundle.
            $bundle_keys = array_keys($bundle_info);
            $bundle = array_shift($bundle_keys);
            $field_definitions = $this->entityManager()->getFieldDefinitions($entity_type_id, $bundle);
            foreach ($field_definitions as $field_name => $field) {
              if (!empty($base_fields[$field_name])) {
                continue;
              }
              $row = array(
                $field_name,
                $field->getType(),
                $field->isRequired() ? 'TRUE' : 'FALSE',
                $field->getDescription(),
              );
              $return[$route_name]['detail']['#rows'][] = $row;
            }
          }
        }
      }
    }
    if ($first) {
      // No matching enabled routes for this path, return not found.
      throw new NotFoundHttpException();
    }
    $return['link'] = array(
      '#markup' => $this->l($this->t('Back to overview'), Url::fromRoute('rest_api_doc.documentation_summary')),
    );

    return $return;
  }