We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
  • As proposed in JIRA (http://tracker.modx.com/issues/8272), editing resource group policy could be a tedious process especially when we have large resources and the policy changes.

    This plugin tries to simplify the process, which will check all nested parent (container) policy and apply it to the current request--without having to set resource group policy for each (child) resource.


    <?php
    /**
     * nestedReourceGroupPolicy plugin
     * ------------------
     * A general purpose for checking resource permission
     * - apply parents's resource group policy
     * - redirect or forward user to login page if required
     *
     * Requirement:
     * - Attach system event "OnWebPageInit" onto this plugin
     * - Create new context/system setting: nested_resource_group. Set it to "1" (or "true")
     *   to apply parents's Resource Groups policy for current request.
     * - Create new context/system setting: login_page (resource ID for login page)
     *   or set it on this plugin as scriptproperties, klik tab Properties > create property: login_page.
     * - Create new context/system setting: login_redirect. Set "forward" or "redirect" as its value.
     * 
    **/
    
    //don't process this plugin on manager context or any context we want
    $excludeContext = array('mgr');
    if (in_array($modx->context->get('key'), $excludeContext)) return;
    
    global $checkResourceIdentifier;
    if (!isset($checkResourceIdentifier)) { 
        //invoked on "OnWebPageInit" when $modx->resourceIdentifier has been set properly
        //and save "default" resource ID on GLOBAL $checkResourceIdentifier
        $checkResourceIdentifier = $modx->resourceIdentifier;
        $nested_resource_group   = $modx->getOption('nested_resource_group', $scriptProperties, 0);
        $nested_resource_group   = $nested_resource_group == 'true' ? 1 : 0; 
        
        if (intval($nested_resource_group) == 1 && intval($checkResourceIdentifier) > 0) {
            $parentIds = $modx->getParentIds(intval($checkResourceIdentifier));
            $parentIds = array_diff($parentIds , array(0));
        
            if (sizeof($parentIds) > 0) {
                $c = $modx->newQuery('modResource');
                $c->where(array(
                    'id:IN' => array_values($parentIds),
                    'deleted' => false,
                    'published' => true
                ));
                $resources = $modx->getCollection('modResource',$c);
            
                if (sizeof($resources) < sizeof($parentIds)) {
                    $checkResourceGroups = false;
                    //get login_page, unauthorized_page and error_page
                    $E401 = $modx->getOption('unauthorized_page', $scriptProperties, 0);
                    $E404 = $modx->getOption('error_page', $scriptProperties, 0);
                    $login_page = intval($modx->getOption('login_page', $scriptProperties, 0));
                    $login_redirect = $modx->getOption('login_redirect', $scriptProperties, 'redirect');
        
                    //don't process if "default" resource ID was error_page, unauthorized_page or login_page
                    if ($checkResourceIdentifier == $E401 || $checkResourceIdentifier == $E404 || $checkResourceIdentifier == $login_page) return '';
                    $checkResourceIdentifier = 0;
                    
                    if (!$modx->user->hasSessionContext($modx->context->get('key')) && $login_page > 0) {
                        //if not logged in? redirect to login page
                        if ($login_redirect == 'forward') {
                            $modx->sendForward($login_page);
                        } else {
                            $modx->sendRedirect($modx->makeUrl($login_page, "", "", 'full'));
                        }                    
                    } else {
                        //if logged in but have no privilege? send 401 unauthorized_page instead of 404 error_page
                        $modx->sendUnauthorizedPage();
                    }                
                }
            }
        }
    }
    


    Note:
    I found related function like findPolicy() and checkPolicy(), but I can't make it works. So... there may be a better and faster approach than use query to get all parent resources.
      zaenal.lokamaya
    • Here related post: "Redirect to login page" using plugin
      http://forums.modx.com/thread/44828/redirect-to-login-page?page=2#dis-post-397761
        zaenal.lokamaya
      • Here complete workaround for checking nested resource group policy and redirecting to login page

        <?php
        /**
         * checkPolicy plugin
         * ------------------
         * A general purpose for checking resource permission
         * - apply nested resource group policy if needed
         * - redirect user to login page if required
         *
         * Requirement:
         * - Attach system event "OnWebPageInit" and "OnPageNotFound" onto this plugin
         * - Create new context/system setting: nested_resource_group. 
         *   Set it to "1" (or "true") to apply parents's Resource Groups policy for current request.
         * - Create new context/system setting: login_page (resource ID for login page)
         *   or set it on this plugin as scriptproperties (klik tab Properties > create property: login_page)
         * - Create new context/system setting: login_redirect. Set "forward" or "redirect" as its value.
         *   Or set it on this plugin as scriptproperties (klik tab Properties > create property: login_redirect)
         * 
        **/
        
        //don't process this plugin on manager context or any context we want
        $excludeContext = array('mgr');
        if (in_array($modx->context->get('key'), $excludeContext)) return;
        
        global $checkResourceIdentifier;
        
        //get login_page, unauthorized_page and error_page
        $E401 = $modx->getOption('unauthorized_page', $scriptProperties, 0);
        $E404 = $modx->getOption('error_page', $scriptProperties, 0);
        $login_page = intval($modx->getOption('login_page', $scriptProperties, 0));
        $login_redirect = $modx->getOption('login_redirect', $scriptProperties, 'redirect');
        
        if (!isset($checkResourceIdentifier)) { 
            //invoked on "OnWebPageInit" when $modx->resourceIdentifier has been set properly
            //and save "default" resource ID on GLOBAL $checkResourceIdentifier
            $checkResourceIdentifier = $modx->resourceIdentifier;
            $nested_resource_group   = $modx->getOption('nested_resource_group', $scriptProperties, 0);
            $nested_resource_group   = $nested_resource_group == 'true' ? 1 : 0; 
            
            if (intval($nested_resource_group) == 1 && intval($checkResourceIdentifier) > 0) {
                $parentIds = array_diff($modx->getParentIds(intval($checkResourceIdentifier)), array(0));
            
                if (sizeof($parentIds) > 0) {
                    $c = $modx->newQuery('modResource');
                    $c->where(array(
                        'id:IN' => array_values($parentIds),
                        'deleted' => false,
                        'published' => true
                    ));
                    $resources = $modx->getCollection('modResource',$c);
                
                    if (sizeof($resources) < sizeof($parentIds)) {
                        unset($resources);
            
                        //don't process if "default" resource ID was error_page, unauthorized_page or login_page
                        if ($checkResourceIdentifier == $E401 || $checkResourceIdentifier == $E404 || $checkResourceIdentifier == $login_page) return '';
                        $checkResourceIdentifier = 0;
                        
                        if (!$modx->user->hasSessionContext($modx->context->get('key')) && $login_page > 0) {
                            //if not logged in? redirect to login page
                            if ($login_redirect == 'forward') {
                                $modx->sendForward($login_page);
                            } else {
                                $modx->sendRedirect($modx->makeUrl($login_page, "", "", 'full'));
                            }                    
                        } else {
                            //if logged in but have no privilege? send 401 unauthorized_page instead of 404 error_page
                            $modx->sendUnauthorizedPage();
                        }                
                    }
                }
            }
        } elseif (isset($checkResourceIdentifier) && intval($checkResourceIdentifier) > 0 && intval($checkResourceIdentifier) == $checkResourceIdentifier) { 
            //invoked on "OnPageNotFound" after modRequest send 404 error
            //and check $checkResourceIdentifier > 0 (resource exist but no privilege)
        
            //don't process if "default" resource ID was error_page, unauthorized_page or login_page
            if ($checkResourceIdentifier == $E401 || $checkResourceIdentifier == $E404 || $checkResourceIdentifier == $login_page) return ''; 
            
            //set $checkResourceIdentifier to 0, to make sure the plugin doesn't make any looping process
            $checkResourceIdentifier = 0;
            
            if (!$modx->user->hasSessionContext($modx->context->get('key')) && $login_page > 0) {
                //if not logged in? redirect to login page
                if ($login_redirect == 'forward') {
                    $modx->sendForward($login_page);
                } else {
                    $modx->sendRedirect($modx->makeUrl($login_page, "", "", 'full'));
                }                    
            } else {
                //if logged in but have no privilege? send 401 unauthorized_page instead of 404 error_page
                $modx->sendUnauthorizedPage();
            }
        }
          zaenal.lokamaya
          • 40147
          • 3 Posts
          I don't quite understand the original requirement/feature request/ but this looks like something that could be very useful...does this plugin automatically update child resources in a resource group, thus eliminating the need to drag/drop new resources?
          • Yes, this plugin will eliminating the need to drag/drop resource in resource group because child resource will inherit parent resource group--without updating the child resources.

            For example (see below), we have 2 resource group: "Teach Policy" and "Private Policy". Then we drag Teachers to "Teach Policy" resource group and Online Resource to "Private Policy", then Video resource will inherit "Private Policy" and "Teach Policy".

            Actually Video resource did not have "Private Policy" and "Teach Policy", its only inherited it from its parents.


            Teachers <-- "Teach Policy"
            + Exam
            + Online Resource <-- "Private Policy"
            ++ Video
              zaenal.lokamaya
              • 23510
              • 168 Posts
              Thanks a lot for this plugin. Something like this needs to be baked into MODx. I don't see how others with 100+ page sites were able to easily manage their Resource Groups.

              J.



              Quote from: lokamaya at Sep 18, 2012, 10:34 AM
              Yes, this plugin will eliminating the need to drag/drop resource in resource group because child resource will inherit parent resource group--without updating the child resources.

              For example (see below), we have 2 resource group: "Teach Policy" and "Private Policy". Then we drag Teachers to "Teach Policy" resource group and Online Resource to "Private Policy", then Video resource will inherit "Private Policy" and "Teach Policy".

              Actually Video resource did not have "Private Policy" and "Teach Policy", its only inherited it from its parents.


              Teachers <-- "Teach Policy"
              + Exam
              + Online Resource <-- "Private Policy"
              ++ Video