You are here

function opigno_learning_path_group_access in Opigno Learning path 3.x

Same name and namespace in other branches
  1. 8 opigno_learning_path.module \opigno_learning_path_group_access()

Restricts user access to Learning Path and it's content.

Implements hook_ENTITY_TYPE_access().

File

./opigno_learning_path.module, line 1687
Contains opigno_learning_path.module.

Code

function opigno_learning_path_group_access(Group $group, $operation, AccountInterface $account) {
  $opigno_types = [
    'learning_path',
    'opigno_course',
    'opigno_class',
  ];
  $group_type = $group
    ->bundle();
  if (!in_array($group_type, $opigno_types)) {
    return AccessResult::neutral();
  }
  $is_platform_cm = $account
    ->hasPermission('manage group content in any group');
  $is_platform_um = $account
    ->hasPermission('manage group members in any group');
  $group_visibility = NULL;
  if ($group
    ->hasField('field_learning_path_visibility')) {
    $group_visibility = $group
      ->get('field_learning_path_visibility')->value;
  }
  switch ($operation) {
    case 'join':

      // This is currently only used for the entity.group.join route but may be
      // applied to other cases such as join/signup links, so as well as the
      // visibility check, additional check the 'join group' permission which is
      // already on the route.
      if ($account
        ->isAnonymous() && $group_visibility == 'semiprivate') {
        return Accessresult::forbidden();
      }

      // Restrict access to any users to join to private Training.
      if ($group_visibility == 'private') {
        return Accessresult::forbidden();
      }
      if ($group
        ->hasPermission('join group', $account)) {
        return AccessResult::allowed();
      }
      break;
    case 'view':
    case 'view teaser':
    case 'take':
      if ($is_platform_cm || $is_platform_um) {

        // Allow platform-level managers to view any group.
        return AccessResult::allowed();
      }
      $group_owner_id = (int) $group
        ->getOwnerId();
      $account_id = (int) $account
        ->id();
      $is_owner = $group_owner_id === $account_id;
      if ($is_owner) {

        // Allow view own groups.
        return AccessResult::allowed();
      }
      if ($group
        ->hasField('field_learning_path_published')) {
        $is_published = $group->field_learning_path_published->value;
        if (!$is_published) {
          $training_role_allowed = FALSE;
          if ($member = $group
            ->getMember($account)) {
            $roles = $member
              ->getRoles();
            foreach ([
              'learning_path-user_manager',
              'learning_path-content_manager',
            ] as $role) {
              if (array_key_exists($role, $roles)) {
                $training_role_allowed = TRUE;
                break;
              }
            }
          }
          if (!$training_role_allowed) {

            // Deny if group unpublished and user has no admin or manager roles.
            return AccessResult::forbidden();
          }
        }
      }
      switch ($group_type) {
        case 'learning_path':
          $membership = $group
            ->getMember($account);
          $is_member = $membership !== FALSE;

          // Deny if there are unfinished required trainings.
          // Don't block training admins and group managers.
          if ($operation == 'take' && (!$group
            ->hasPermission('administer members', $account) || !$group
            ->hasPermission('edit group', $account))) {

            // List of required trainings that should to be finished by user
            // before he can start a current training.
            $uncompleted = LearningPathAccess::hasUncompletedRequiredTrainings($group, $account);
            if (!empty($uncompleted)) {
              return AccessResult::forbidden();
            }
          }
          switch ($group_visibility) {
            case 'public':

              // Restrict access to public training with price for Anonymous.
              if ($account
                ->isAnonymous() && $group
                ->hasField('field_lp_price') && $group
                ->get('field_lp_price')->value) {
                return AccessResult::forbidden();
              }
              return AccessResult::allowed();
            case 'semiprivate':
              $group_hide_for_anonymous = $group->field_anonymous_visibility->value;
              $is_anonymous = $account
                ->isAnonymous();
              if ($group_hide_for_anonymous && $is_anonymous) {

                // Deny access if group is hidden for anonymous users
                // and current user is an anonymous.
                return AccessResult::forbidden();
              }
              if ($operation == 'take' && (!$is_member || $is_anonymous)) {
                return AccessResult::forbidden();
              }

              // Check if we need to wait validation.
              $is_valid = LearningPathAccess::statusGroupValidation($group, $account);
              if ($operation == 'take' && !$is_valid) {

                // Deny access if user is a blocked or non-activated member
                // of current group, viewing not a group homepage
                // and group requires validation.
                return AccessResult::forbidden();
              }
              return AccessResult::allowed();
            case 'private':
              $is_valid = $is_member && LearningPathAccess::statusGroupValidation($group, $account);
              return $is_valid ? AccessResult::allowed() : AccessResult::forbidden();
          }
          break;
        case 'opigno_course':
        case 'opigno_class':
          $is_valid = LearningPathAccess::checkCourseClassAccess($group, $account);
          return $is_valid ? AccessResult::allowed() : AccessResult::forbidden();
      }
      break;
    case 'update':
      $is_group_cm = $group
        ->hasPermission('edit group', $account);
      switch ($group_type) {
        case 'opigno_class':

          // Allow user managers to edit class.
          return $is_platform_um || $is_group_cm ? AccessResult::allowed() : AccessResult::forbidden();
      }

      // Allow content managers to edit group.
      return $is_platform_cm || $is_group_cm ? AccessResult::allowed() : AccessResult::forbidden();
    case 'delete':
      $is_group_cm = $group
        ->hasPermission('delete group', $account);
      switch ($group_type) {
        case 'opigno_class':

          // Allow user managers to delete class.
          return $is_platform_um || $is_group_cm ? AccessResult::allowed() : AccessResult::forbidden();
      }

      // Allow content managers to delete group.
      return $is_platform_cm || $is_group_cm ? AccessResult::allowed() : AccessResult::forbidden();
    case 'administer members':
      $is_group_um = $group
        ->hasPermission('administer members', $account);

      // Allow user managers to manage members.
      return $is_platform_um || $is_group_um ? AccessResult::allowed() : AccessResult::forbidden();
    case 'view certificate':
      $completed = opigno_learning_path_completed_on($group
        ->id(), $account
        ->id(), TRUE);
      return $completed ? AccessResult::allowed() : AccessResult::forbidden();
  }
  return AccessResult::neutral();
}