1

I've made some custom entities using the Entity API and I would like to give some users the ability to add bundles to them.

However it seems that in order to add bundles they have to have the "Administer site configuration" permission. I am a bit concerned about giving users that, especially as we might be doing a multisite system where different organisations will own different sites. I'm worried that they might be able configure directories and file paths and end up getting access to things on the other sites.

There is a special permission for creating content types, so I wonder whether there could also be one for creating bundles of other kinds of entities. It seems an oversight that there is not.

  • Drupal isn’t aware of your custom entities or bundles like that. But you can implement a permissions callback and create them dynamically per bundle, and then use them in access checks. – Kevin Apr 6 '18 at 13:21
  • I wrote about this a little bit ago. This is for taxonomy terms, but you can use it as a guideline to implementing for your entity type: kevinquillen.com/drupal/2016/02/21/… – Kevin Apr 6 '18 at 13:35
  • I've got halfway there. I used the drupal console entity generator to make the entities, and told it I wanted bundles. This tells it to generate files in src/Entity called FooType.php etc. In those files, there is an "admin_permission" setting that defaults to "administer site configuration". You can create a custom permission for each entity in <module>.permissions.yml and use that instead. However, although this allows the user to create new bundles, it does not allow them to add any fields! – naomi Apr 27 '18 at 17:44
3

Writing in here, since its a faux paux to link to blog articles.

In your permissions.yml file of your module, you can define a permissions callback like so:

permission_callbacks:
  - Drupal\mymodule\MyModulePermissions::permissions

Then in your MyModulePermissions class:

namespace Drupal\mymodule;

use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;

class MyModulePermissions implements ContainerInjectionInterface {

  use StringTranslationTrait;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Constructor for MyModulePermissions.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container->get('entity_type.manager'));
  }

  /**
   * Get permissions for MyModule.
   *
   * @return array
   *   Permissions array.
   */
  public function permissions() {
    $permissions = [];

    foreach ($this->entityTypeManager->getStorage('myentity')->loadMultiple() as $type) {
      $permissions += [
        'create ... ' . $type->bundle() => [
          'title' => $this->t('Allow creation of %type', array('%type' => $type->label())),
        ]
      ];

      $permissions += [
        'update ... ' . $type->bundle() => [
          'title' => $this->t('Allow update of %type', array('%type' => $type->label())),
        ]
      ];

      $permissions += [
        'delete ... ' . $type->bundle() => [
          'title' => $this->t('Allow deletion of %type', array('%type' => $type->label())),
        ]
      ];
    }

    return $permissions;
  }
}

Something like that. Code is untested. This will loop through and create CRUD permissions for each bundle.

  • Thanks for the comprehensive reply but I don't think it answers my question. I asked how to allow users to create bundles. E.g. if the entity type is Person, I want users to have the permission to create types of Person like Volunteer, Client. To create the actual bundles themselves. Not how to grant CRUD permissions on entities of that type once the bundle exists already - which is what I think your code does – naomi Apr 27 '18 at 14:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.