PermissionHandler.php 5.71 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?php

/**
 * @file
 * Contains \Drupal\user\PermissionHandler.
 */

namespace Drupal\user;

use Drupal\Component\Discovery\YamlDiscovery;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;

/**
 * Provides the available permissions based on hook_permission and yml files.
 *
 * To define permissions you can use a $module.permissions.yml file:
 *
 * @code
 * 'access all views':
 *   title: 'Bypass views access control'
 *   description: 'Bypass access control when accessing views.'
 *   'restrict access': TRUE
 * @encode
 *
 * @see hook_permission()
 */
class PermissionHandler implements PermissionHandlerInterface {

  use StringTranslationTrait;

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The YAML discovery class to find all .permissions.yml files.
   *
   * @var \Drupal\Component\Discovery\YamlDiscovery
   */
  protected $yamlDiscovery;

  /**
   * Constructs a new PermissionHandler.
   *
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
   *   The string translation.
   */
  public function __construct(ModuleHandlerInterface $module_handler, TranslationInterface $string_translation) {
    // @todo It would be nice if you could pull all module directories from the
    //   container.
    $this->moduleHandler = $module_handler;
    $this->stringTranslation = $string_translation;
  }

  /**
   * Gets the YAML discovery.
   *
   * @return \Drupal\Component\Discovery\YamlDiscovery
   *   The YAML discovery.
   */
  protected function getYamlDiscovery() {
    if (!isset($this->yamlDiscovery)) {
      $this->yamlDiscovery = new YamlDiscovery('permissions', $this->moduleHandler->getModuleDirectories());
    }
    return $this->yamlDiscovery;
  }

  /**
   * {@inheritdoc}
   */
  public function getPermissions() {
    $all_permissions = $this->buildPermissionsYaml();

    $all_permissions += $this->buildPermissionsModules();

83
    return $this->sortPermissions($all_permissions);
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
  }

  /**
   * Builds all permissions provided by .permissions.yml files.
   *
   * @return array[]
   *   Each return permission is an array with the following keys:
   *   - title: The title of the permission.
   *   - description: The description of the permission, defaults to NULL.
   *   - provider: The provider of the permission.
   */
  protected function buildPermissionsYaml() {
    $all_permissions = array();
    foreach ($this->getYamlDiscovery()->findAll() as $provider => $permissions) {
      foreach ($permissions as &$permission) {
        if (!is_array($permission)) {
          $permission = array(
            'title' => $permission,
          );
        }
        $permission['title'] = $this->t($permission['title']);
        $permission['description'] = isset($permission['description']) ? $this->t($permission['description']) : NULL;
        $permission['provider'] = $provider;
      }
      $all_permissions += $permissions;
    }
    return $all_permissions;
  }

  /**
   * Builds all permissions provided by .module files.
   *
   * @return array[]
   *   Each return permission is an array with the following keys:
   *   - title: The title of the permission.
   *   - description: The description of the permission, defaults to NULL.
   *   - provider: The provider of the permission.
   */
  protected function buildPermissionsModules() {
    $all_permissions = array();
    foreach ($this->moduleHandler->getImplementations('permission') as $provider) {
      $permissions = $this->moduleHandler->invoke($provider, 'permission');
      foreach ($permissions as &$permission) {
        if (!is_array($permission)) {
          $permission = array(
            'title' => $permission,
            'description' => NULL,``
          );
        }
        $permission['provider'] = $provider;
      }
      $all_permissions += $permissions;
    }
    return $all_permissions;
  }

  /**
141
   * Sorts the given permissions by provider name and title.
142
143
144
145
146
147
148
149
150
151
   *
   * @param array $all_permissions
   *   The permissions to be sorted.
   *
   * @return array[]
   *   Each return permission is an array with the following keys:
   *   - title: The title of the permission.
   *   - description: The description of the permission, defaults to NULL.
   *   - provider: The provider of the permission.
   */
152
  protected function sortPermissions(array $all_permissions = array()) {
153
154
155
156
157
    // Get a list of all the modules providing permissions and sort by
    // display name.
    $modules = $this->getModuleNames();

    uasort($all_permissions, function (array $permission_a, array $permission_b) use ($modules) {
158
159
160
161
162
163
      if ($modules[$permission_a['provider']] == $modules[$permission_b['provider']]) {
        return $permission_a['title'] > $permission_b['title'];
      }
      else {
        return $modules[$permission_a['provider']] > $modules[$permission_b['provider']];
      }
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
    });
    return $all_permissions;
  }

  /**
   * Returns all module names.
   *
   * @return string[]
   *   Returns the human readable names of all modules keyed by machine name.
   */
  protected function getModuleNames() {
    $modules = array();
    $module_info = $this->systemRebuildModuleData();
    foreach (array_keys($this->moduleHandler->getModuleList()) as $module) {
      $modules[$module] = $module_info[$module]->info['name'];
    }
    asort($modules);
    return $modules;
  }

  /**
   * Wraps system_rebuild_module_data()
   *
   * @return \Drupal\Core\Extension\Extension[]
   */
  protected function systemRebuildModuleData() {
    return system_rebuild_module_data();
  }

}