- π©πͺGermany thomas.wardin
Sorry for asking: Is such a plugin existing? How to install/make available to the module? How to protect against overwriting by updates?
- Status changed to Active
about 1 year ago 6:20am 25 August 2023 - πΊπΈUnited States josh.estep
My issue, perhaps appropriate for this thread, was that I need to be able to support multiple IMCE configuration profiles associated with a given user where each profile assigns different permissions to a single folder.
To solve this, I updated userProfile() in IMCE.php to iterate over the different permissions for a given folder and then merge.
+ // Get IMCE settings and role-profile mappings + $imce_settings = \Drupal::config('imce.settings'); + $storage = \Drupal::entityTypeManager()->getStorage('imce_profile'); + $roles_profiles = $imce_settings->get('roles_profiles'); + $user_roles = array_flip($user->getRoles()); + + // Initialize an array to hold the most permissive permissions for each folder + $folder_perms = []; + + // Loop through user roles to get profile configurations + foreach ($user_roles as $rid => $role) { + // Check if the role has a profile mapping + if (isset($role) && !empty($roles_profiles[$rid][$scheme])) { + // Load the IMCE profile and its config + $test_config = $storage->load($roles_profiles[$rid][$scheme]); + $profile_config = $test_config->getConf(); + + // Loop through folders in profile to keep the most permissive permissions + foreach ($profile_config['folders'] as $folder) { + $path = $folder['path']; + if (!isset($folder_perms[$path])) { + $folder_perms[$path] = []; + } + foreach ($folder['permissions'] as $perm => $value) { + // Store the most permissive value of each permission + if ($perm === 'all' || !isset($folder_perms[$path][$perm]) || $value > $folder_perms[$path][$perm]) { + $folder_perms[$path][$perm] = $value; + } + } + } + } + } + + // Convert the permissive permissions back to the original folder array format + $conf['folders'] = []; + foreach ($folder_perms as $path => $permissions) { + $conf['folders'][] = ['path' => $path, 'permissions' => $permissions]; + } return static::processUserConf($conf, $user);
This probably needs to be updated to use dependency injection, but I hope this helps somebody else.
Here is a sample plugin for above.
Note it would break complex permissions, for example block rules below or beside allow rules.
web/modules/custom/zzz/src/Plugin/ImcePlugin/ZzzImceFolders.php
namespace Drupal\zzz\Plugin\ImcePlugin; use Drupal\Core\Session\AccountProxyInterface; use Drupal\imce\Imce; use Drupal\imce\ImcePluginBase; /** * Custom IMCE folder perms merge. * * @ImcePlugin( * id = "zzz_imce_folders", * label = "IMCE ZZZ Folders", * weight = 10, * ) * * Explain. */ class ZzzImceFolders extends ImcePluginBase { /** * {@inheritdoc} */ public function processUserConf(array &$conf, AccountProxyInterface $user) { // Skip administrators. if ($user->hasPermission("administer imce")) { return; } // Skip admin roles. if (array_intersect($user->getRoles(), [ 'administrator', 'custom_client_admin', ])) { return; } // Get imce settings. $settings = \Drupal::config('imce.settings'); $imce_roles = $settings->get('roles_profiles'); // Get user roles, from more permissive to less permissive. $user_roles = array_reverse(array_flip($user->getRoles())); $user_imce_roles = array_keys(array_intersect_key($imce_roles, $user_roles)); // Get storage. $scheme = \Drupal::config('system.file')->get('default_scheme'); $storage = \Drupal::entityTypeManager()->getStorage('imce_profile'); // Get folders for each role. foreach ($user_imce_roles as $id) { if ($profile = $storage->load($imce_roles[$id][$scheme])) { if ($folders = $profile->getConf('folders', [])) { $processed = Imce::processUserFolders($folders, $user); $conf['folders'][$id] = $processed; } } } } }