Making WordPress.org

Changeset 1834


Ignore:
Timestamp:
08/19/2015 04:20:40 AM (9 years ago)
Author:
dd32
Message:

Translate: Rosetta Roles: Modularize the checks to make it easier for other GlotPress plugins/templates to customize the UI based on a Translators permissions.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/translate.wordpress.org/includes/gp-plugins/wporg-rosetta-roles/wporg-rosetta-roles.php

    r1785 r1834  
    5252     */
    5353    public function pre_can_user( $verdict, $args ) {
     54        // Administrators on global.wordpress.org are considered global admins in GlotPress.
     55        if ( $this->is_global_administrator( $args['user_id'] ) ) {
     56            return true;
     57        }
     58
     59        if ( $args['action'] !== 'approve' || ! in_array( $args['object_type'], array( 'project|locale|set-slug', 'translation-set' ) ) ) {
     60            return false;
     61        }
     62
     63        // Get locale and current project ID.
     64        $locale_and_project_id = (object) $this->get_locale_and_project_id( $args['object_type'], $args['object_id'] );
     65        if ( ! $locale_and_project_id ) {
     66            return false;
     67        }
     68
     69        $locale_slug = $locale_and_project_id->locale;
     70        $current_project_id = $locale_and_project_id->project_id;
     71
     72        // Simple check to see if they're an approver or not
     73        if ( ! $this->is_approver_for_locale( $args['user_id'], $locale_slug ) ) {
     74            return false;
     75        }
     76
     77        // Grab the list of Projects (or 'all') that the user can approve
     78        $project_access_list = $this->get_project_id_access_list( $args['user_id'], $locale_slug );
     79        if ( ! $project_access_list ) {
     80            return false;
     81        }
     82
     83        // Short circuit the check if user can approve all projects.
     84        if ( in_array( 'all', $project_access_list ) ) {
     85            return true;
     86        }
     87
     88        // If current project is a parent ID.
     89        if ( in_array( $current_project_id, $project_access_list ) ) {
     90            return true;
     91        }
     92
     93        // A user is allowed to approve sub projects as well.
     94        $project_access_list = $this->get_project_id_access_list( $args['user_id'], $locale_slug, /* $include_children = */ true );
     95        if ( in_array( $current_project_id, $project_access_list ) ) {
     96            return true;
     97        }
     98
     99        return false;
     100    }
     101
     102    /**
     103     * Determine if a given user is a Global Admin.
     104     *
     105     * Users present as an administrator on global.wordpress.org are treated as a
     106     * global administrator in GlotPress.
     107     *
     108     * @param int $user A BackPress User object or user ID for the user to check.
     109     *
     110     * @return bool
     111     */
     112    public function is_global_administrator( $user_id ) {
    54113        if ( ! class_exists( 'BP_Roles' ) ) {
    55114            require_once( BACKPRESS_PATH . 'class.bp-roles.php' );
     
    59118        }
    60119
    61         // Current user.
    62         $user = new BP_User( $args['user_id'] );
     120        $user = new BP_User( $user_id );
    63121
    64122        // 115 = global.wordpress.org. Administrators on this site are considered global admins in GlotPress.
     
    67125        }
    68126
    69         if ( $args['action'] !== 'approve' || ! in_array( $args['object_type'], array( 'project|locale|set-slug', 'translation-set' ) ) ) {
    70             return false;
    71         }
    72 
    73         // Get locale and current project ID.
    74         $locale_and_project_id = (object) $this->get_locale_and_project_id( $args['object_type'], $args['object_id'] );
    75         if ( ! $locale_and_project_id ) {
    76             return false;
    77         }
    78 
    79         $locale_slug = $locale_and_project_id->locale;
    80         $current_project_id = $locale_and_project_id->project_id;
     127        return false;
     128    }
     129
     130    /**
     131     * Determine if a given user is a Translation Approver for a Locale.
     132     *
     133     * @param int $user A BackPress User object or user ID for the user to check.
     134     *
     135     * @return bool
     136     */
     137    public function is_approver_for_locale( $user_id, $locale_slug ) {
     138        if ( ! class_exists( 'BP_Roles' ) ) {
     139            require_once( BACKPRESS_PATH . 'class.bp-roles.php' );
     140        }
     141        if ( ! class_exists( 'BP_User' ) ) {
     142            require_once( BACKPRESS_PATH . 'class.bp-user.php' );
     143        }
    81144
    82145        // Get blog prefix of the associated Rosetta site.
     
    84147            return false;
    85148        }
     149
     150        $user = new BP_User( $user_id );
    86151
    87152        // Check if current user has the approver role.
     
    92157        }
    93158        $user->get_role_caps();
    94         if ( ! $user->has_cap( $this->approver_role ) ) {
     159
     160        return $user->has_cap( $this->approver_role );
     161
     162    }
     163
     164    /**
     165     * Retrieve a list of Project ID's which the current user can approve for.
     166     *
     167     * This is likely to be incorrrect in the event that the user is a Translation Editor or Global Admin.
     168     * The array item 'all' is special, which means to allow access to all projects.
     169     *
     170     * @param int    $user            A BackPress User object or user ID for the user to check.
     171     * @param string $locale_slug     The Locale for which we are checking
     172     * @param int    $include_children Whether to include the children project ID's in the return
     173     *
     174     * @return array A list of the Project ID's for which the current user can approve translations for.
     175     */
     176    public function get_project_id_access_list( $user_id, $locale_slug, $include_children = false ) {
     177        if ( ! class_exists( 'BP_Roles' ) ) {
     178            require_once( BACKPRESS_PATH . 'class.bp-roles.php' );
     179        }
     180        if ( ! class_exists( 'BP_User' ) ) {
     181            require_once( BACKPRESS_PATH . 'class.bp-user.php' );
     182        }
     183
     184        $user = new BP_User( $user_id );
     185
     186        // Get blog prefix of the associated Rosetta site.
     187        if ( ! $blog_prefix = $this->get_blog_prefix( $locale_slug ) ) {
    95188            return false;
    96189        }
    97190
    98191        // Get IDs of projects which the user can approve.
    99         $meta_key =  $blog_prefix . $this->project_access_meta_key;
     192        $meta_key = $blog_prefix . $this->project_access_meta_key;
    100193        if ( empty( $user->$meta_key ) || ! is_array( $user->$meta_key ) ) {
    101194            return false;
     
    104197        $project_access_list = $user->$meta_key;
    105198
    106         // Short circuit the check if user can approve all projects.
    107         if ( in_array( 'all', $project_access_list ) ) {
    108             return true;
    109         }
    110 
    111         // If current project is a parent ID.
    112         if ( in_array( $current_project_id, $project_access_list ) ) {
    113             return true;
     199        // If we don't want the children, or the user has access to all projects.
     200        if ( ! $include_children || in_array( 'all', $project_access_list ) ) {
     201            return $project_access_list;
    114202        }
    115203
     
    117205        $allowed_sub_project_ids = array();
    118206        foreach ( $project_access_list as $project_id ) {
     207            if ( 'all' === $project_id ) {
     208                continue;
     209            }
    119210            $sub_project_ids = $this->get_sub_project_ids( $project_id );
    120211            if ( $sub_project_ids ) {
     
    122213            }
    123214        }
    124         $allowed_sub_project_ids = array_unique( $allowed_sub_project_ids );
    125 
    126         if ( in_array( $current_project_id, $allowed_sub_project_ids ) ) {
    127             return true;
    128         }
    129 
    130         return false;
     215
     216        $project_access_list = array_merge( $project_access_list, $allowed_sub_project_ids );
     217        $project_access_list = array_unique( $project_access_list );
     218
     219        return $project_access_list;
    131220    }
    132221
Note: See TracChangeset for help on using the changeset viewer.