We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 47212
    • 40 Posts
    Hello,

    I think I want to do something that it's not possible with Modx but I am not sure.

    I have a super-admin user group that can associate resources to the "super admin restricted" resource group to hide them to all other users.

    I have also 3 basic user groups, and each of these have an associated resource group to only view the resources from their group. The resources of these 3 user groups are managed by a sub-admin (not part of the super-admin group) that can assign one resource to any of the 3 associated resource groups of these 3 basic user groups.

    But I don't want this sub-admin group to be able to set the "super admin restricted" resource group, I only want them to be able to list or set the resource groups he has access to.



    Unfortunately, I can't find what I want in the ACL.

    If I give to this sub-admin group the ability to associate a resource to a resource group, they can do it with all resource groups. I can't prevent them to associate a resource with the "super admin restricted" resource group.




    It does not seem to be very complicated, it's a common use case.

    Any idea of what I'm doing wrong?
      • 3749
      • 24,544 Posts
      MODX should do that automatically, but I don't think it does. I can't think of any easy way to accomplish it, but it's a good feature request.

      The only way to do it that I can think of would be to use JavaScript to find the <tr> tag that shows the resource group's row, and set it to "display:none". Unfortunately, it doesn't have an ID or a class, so getting a reference to it will be difficult, but not impossible.

        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 47212
        • 40 Posts
        I ended up with the same idea ! We are so connected.

        In fact, there is a id for the resource group tab, so I did manage to get reference to all of the tr.

        I got the resource group names to perform a string comparaison, it works well.

        Here is my implementation, maybe it could be improved by using modx API instead of PDO but I personally prefer to deal directly with the tables and datas since I know them very well instead of losing time to learn the Modx ORM where the result in the database is never ensured.

        <?php
        $eventName = $modx->event->name;
        switch($eventName) {
            case 'OnDocFormPrerender':
                try {
                    // Only use this plugin on a resource form
                    if (preg_match('/^resource/', $_GET['a'])) {
        
                        // Get user groups
                        $resourceGroups = $modx->user->getUserGroups();                
        
                        // Id of the specific user group where we want to hide the resource groups
                        if (in_array(8, $resourceGroups)) {
                            // Db connection
                            $db = new PDO('mysql:host=' . getenv('DB_SERVER') . ';dbname=' . getenv('DB_NAME') . ';charset=utf8', getenv('DB_USER'), getenv('DB_PASSWORD'));
        
                            // List of the resource group ids whe want to hide for that specific user group
                            $resourcegroupdIds = '9,10,11,12,13,14,15';
        
                            // Get the names of these resource groups
                            $req = $db->query('SELECT name FROM modx_documentgroup_names WHERE id IN (' . $resourcegroupdIds . ')');
                            $result = $req->fetchAll();
                            if (!json_encode($result)) { throw new Exception('Unable to parse the result of the resource group names query.'); }
                            $req->closeCursor();
        
                            // Get an array of string
                            $resourcegroupNames = array_map(function($value) { return $value['name']; }, $result);
        
                            // Encode the array in JSON to use it in JavaScript
                            $resourcegroupNamesAsJSON = json_encode($resourcegroupNames, JSON_UNESCAPED_UNICODE);
        
                            // Remove unwanted resource groups
                            $js ="<script>
                                Ext.onReady(function () {
                                    setTimeout(() => {
                                        // Set our array of resource group names
                                        let resourcegroupNames = " . json_encode($resourcegroupNames, JSON_UNESCAPED_UNICODE) . ";
                                        // Get resource group rows and convert it from NodeList to Array to use a for loop
                                        let resourcegroupRows = [].slice.call(document.querySelectorAll('#modx-resource-access-permissions .x-grid3-row'));
        
                                        // Loop over each row
                                        for (const resourcegroupRow of resourcegroupRows) {
                                            // For each row, loop over each resource group name
                                            for (const resourcegroupName of resourcegroupNames) {
                                                // If name matches, we hide it
                                                if (resourcegroupRow.textContent.trim() === resourcegroupName) {
                                                    resourcegroupRow.style.display = 'none';
                                                }
                                            }
                                        }
                                    }, 1);
                                });
                                </script>";
                            $modx->regClientStartupHTMLBlock($js);
                            $modx->log(xPDO::LOG_LEVEL_DEBUG, 'Resource groups were removed from the resource list.');
                        }
                    }
                }
                catch (Exception $e) {
                    $modx->log(xPDO::LOG_LEVEL_ERROR, $e->getMessage());
                }
            break; 
        }
          • 3749
          • 24,544 Posts
          I'm glad you got it sorted.

          FYI, since you are connecting the plugin only to OnDocFormPrerender, the outer switch statement is unnecessary, unless you're concerned that someone might connect it to another event.

          Similarly:

          if (preg_match('/^resource/', $_GET['a'])) 


          Since OnDocFormPrerender is only invoked from the Create/Edit Resource panel, your code will only execute when editing a modResource object or one of its descendants. If you need to check for weblinks, symlinks, Articles, etc., you have the $resource variable (the modResource object) available automatically and can check the class_key.
            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting