1, 'view_my_invoices' => 1, ); /** * Initialise this object. * * @since 1.0 */ public function __construct() { // Init translation. $this->translation(); // Bail if CiviCRM plugin is not present. if ( ! function_exists( 'civi_wp' ) ) { return; } // Register hooks. $this->register_hooks(); /** * Broadcast that this plugin is now loaded. * * @since 1.0 */ do_action( 'civicrm_permissions_sync_loaded' ); } /** * Register hooks. * * @since 1.0 */ public function register_hooks() { /* * The following two hooks are native to the CiviCRM WordPress plugin. * * If this plugin is not active when CiviCRM itself is activated, then * (obviously) the callbacks will never run. If it is active, however, * then this is quite neat. */ // Filter minimum CiviCRM capabilities. add_filter( 'civicrm_min_capabilities', [ $this, 'capabilities_minimum' ], 20, 1 ); // Sync when CiviCRM activation action fires. add_action( 'civicrm_activation', [ $this, 'capabilities_sync' ], 20 ); /* * If this plugin is activated after CiviCRM itself is activated, then * we need other events to hook into. The 'init' hook is where most * role-related changes are made, so use that. */ // Add to minimum CiviCRM capabilities. add_action( 'init', [ $this, 'capabilities_anon' ], 100 ); // Sync late on init. add_action( 'init', [ $this, 'capabilities_sync' ], 100 ); } /** * Load translation. * * @since 1.0 */ public function translation() { load_plugin_textdomain( 'reset-wp-civicrm-roles-caps', // Unique name. false, // Deprecated argument. dirname( plugin_basename( __FILE__ ) ) . '/languages/' // Relative path. ); } /** * Filter minimum CiviCRM capabilities. * * The standard CiviCRM install misses out a few capabilities which many * installs need to function as expected. They are added here, but may * themselves be filtered if desired. * * @since 1.0 * * @param array $capabilities The existing minimum capabilities. * @return array $capabilities The modified minimum capabilities. */ public function capabilities_minimum( $capabilities = array() ) { // Add our extra capabilities. foreach( $this->min_capabilities AS $capability => $value ) { $capabilities[$capability] = 1; } /** * Allow capabilities to be filtered further. * * @since 1.0 * * @param array $capabilities The minimum capabilities. * @return array $capabilities The modified capabilities. */ $capabilities = apply_filters( 'civicrm_permissions_sync_caps_min', $capabilities ); // --< return $capabilities; } /** * Filter minimum CiviCRM capabilities for the anonymous user. * * This method adds a few capabilities which many CiviCRM installs need to * function as expected. * * @since 1.0 */ public function capabilities_anon() { // Fetch roles object. $wp_roles = wp_roles(); // Bail if the anonymous_user role does not exist. if ( ! $wp_roles->is_role( 'anonymous_user' ) ) { return; } // Get anonymous_user role. $anon = $wp_roles->get_role( 'anonymous_user' ); // Add the capabilities if not already added. foreach( $this->min_capabilities AS $capability => $value ) { if ( ! $anon->has_cap( $capability ) ) { $anon->add_cap( $capability ); } } } /** * Sync capabilities to WordPress. * * Most plugins that deal with capabilities discover them by inspecting the * roles in WordPress. There are other places that some plugins also inspect * such as Custom Post Types and plugins such as WooCommerce and bbPress. We * don't need to concern ourselves with these subsequent inspections, since * adding all CiviCRM permissions to a WordPress role is enough to make them * discoverable. * * @since 1.0 */ public function capabilities_sync() { // Bail if CiviCRM not initialised. if ( ! $this->is_civicrm_initialised() ) { return; } // Get all CiviCRM permissions, excluding disabled components and descriptions. $permissions = CRM_Core_Permission::basicPermissions( false, false ); // Convert to WordPress capabilities. $capabilities = array(); foreach( $permissions AS $permission => $title ) { $capabilities[] = CRM_Utils_String::munge( strtolower( $permission ) ); } /** * Allow administrator-level capabilities to be filtered. * * @since 1.0 * * @param array $capabilities The minimum capabilities. * @return array $capabilities The modified capabilities. */ $capabilities = apply_filters( 'civicrm_permissions_sync_caps_admin', $capabilities ); // Get the role to apply all CiviCRM permissions to. $custom_role = $this->role_get(); // Add the capabilities if not already added. foreach( $capabilities as $capability ) { if ( ! $custom_role->has_cap( $capability ) ) { $custom_role->add_cap( $capability ); } } } /** * Retrieve our custom WordPress role. * * We need a role to which we add all CiviCRM permissions. This makes the * capabilities discoverable by other plugins. This method creates the role * if it doesn't already exist by cloning the 'adminstrator' role. * * @since 1.0 * * @return WP_Role|void $custom_role The custom role, or void on failure. */ public function role_get() { // Fetch roles object. $wp_roles = wp_roles(); // If the custom role already exists. if ( $wp_roles->is_role( $this->custom_role_name ) ) { // Get existing role. $custom_role = $wp_roles->get_role( $this->custom_role_name ); } else { // Bail if the 'administrator' role is not there for some reason. if ( ! $wp_roles->is_role( 'administrator' ) ) { return; } // Grab the 'administrator' role. $admin = $wp_roles->get_role( 'administrator' ); // Add new role. $custom_role = add_role( $this->custom_role_name, __( 'CiviCRM Administrator', 'reset-wp-civicrm-roles-caps' ), $admin->capabilities ); } // If void then log something. if ( empty( $custom_role ) ) { // Construct a message. $message = sprintf( __( 'Could not find CiviCRM sync role: "%s"', 'reset-wp-civicrm-roles-caps' ), $this->custom_role_name ); // Add log entry. $e = new Exception; $trace = $e->getTraceAsString(); error_log( print_r( array( 'method' => __METHOD__, 'message' => $message, 'backtrace' => $trace, ), true ) ); } // --< return $custom_role; } /** * Check if CiviCRM is initialised. * * @since 1.0 * * @return bool True if CiviCRM initialised, false otherwise. */ public function is_civicrm_initialised() { // Init only when CiviCRM is fully installed. if ( ! defined( 'CIVICRM_INSTALLED' ) ) return false; if ( ! CIVICRM_INSTALLED ) return false; // Bail if no CiviCRM init function. if ( ! function_exists( 'civi_wp' ) ) return false; // Try and initialise CiviCRM. return civi_wp()->initialize(); } } // Class ends. /** * Get a reference to this plugin. * * @since 1.0 * * @return CiviCRM_Permissions_Sync $civicrm_permissions_sync The plugin reference. */ function civicrm_permissions_sync() { // Hold the plugin instance in a static variable. static $civicrm_permissions_sync = false; // Instantiate plugin if not yet instantiated. if ( false === $civicrm_permissions_sync ) { $civicrm_permissions_sync = new CiviCRM_Permissions_Sync(); } // --< return $civicrm_permissions_sync; } // Init plugin. add_action( 'plugins_loaded', 'civicrm_permissions_sync' );