You are here

public function OpignoGroupManagedContent::getNextStep in Opigno group manager 3.x

Same name and namespace in other branches
  1. 8 src/Entity/OpignoGroupManagedContent.php \Drupal\opigno_group_manager\Entity\OpignoGroupManagedContent::getNextStep()

Get the next LPManagedContent object according to the user score.

Parameters

int $user_score: The user score for this content.

mixed $attempts: Module attempts.

mixed $module: Module object.

null|bool $guidedNavigation: Group guided navigation option.

null|string $type_id: Step type ID.

Return value

bool|OpignoGroupManagedContent FALSE if no next content. The next OpignoGroupManagedContent if there is a next content.

Throws

\Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException

\Drupal\Component\Plugin\Exception\PluginNotFoundException

File

src/Entity/OpignoGroupManagedContent.php, line 502

Class

OpignoGroupManagedContent
Defines the Opigno Group Content entity.

Namespace

Drupal\opigno_group_manager\Entity

Code

public function getNextStep($user_score, $attempts = NULL, $module = NULL, $guidedNavigation = NULL, $type_id = NULL) {
  if ($type_id != 'ContentTypeCourse') {
    $_SESSION['step_required_conditions_failed'] = FALSE;
  }
  $user_scores = [];

  // Get the child link that has the required_score
  // higher than the $score param
  // and that has the higher required_score.
  $db_connection = \Drupal::service('database');
  $query = $db_connection
    ->select('opigno_group_link', 'ogl');
  $query
    ->fields('ogl', [
    'id',
    'required_score',
  ]);
  $query
    ->condition('parent_content_id', $this
    ->id());
  $query
    ->condition('required_score', $user_score, '<=');
  $query
    ->orderBy('required_score', 'DESC');

  // To preserve the same order between multiple queries
  // when the required_score is equal.
  $query
    ->orderBy('id');
  $query
    ->execute()
    ->fetchAllAssoc('id');
  $query
    ->range(0, 1);
  $result = $query
    ->execute()
    ->fetchObject();
  $no_conditions_met = TRUE;
  if ($result) {
    $next_step_id = $result->id;
    if ($result->required_score > 0) {

      // Required score achieved.
      $no_conditions_met = FALSE;
    }
  }

  // Get required conditions.
  $required_conditions = $db_connection
    ->select('opigno_group_link', 'ogl')
    ->fields('ogl', [
    'id',
    'required_score',
    'required_activities',
  ])
    ->condition('parent_content_id', $this
    ->id())
    ->condition('group_id', $this
    ->getGroupId())
    ->execute()
    ->fetchAllAssoc('id');

  // Set branching mode flag.
  $required_flag = FALSE;
  $min_score = $this
    ->getSuccessScoreMin();
  if ($this
    ->isMandatory()) {
    if ($min_score === '0' || $user_score >= $min_score) {
      $required_flag = TRUE;
    }
  }
  else {
    $required_flag = TRUE;
  }

  // Handle LP modules links conditions.
  // Required score and activities/answers.
  if ($required_flag && $required_conditions && $attempts) {
    foreach ($attempts as $id => $module_attempts) {
      if (!empty($module_attempts)) {
        $last_attempts[$id] = $module_attempts[max(array_keys($module_attempts))];

        // Handle user score depending to keeping results option.
        $type_id = $module
          ->getEntityTypeId();
        if ('opigno_module' === $type_id && in_array($module
          ->getKeepResultsOption(), [
          'newest',
          'all',
        ])) {
          $last = reset($last_attempts);
          if (!empty($last)) {
            $user_scores[$id] = $last
              ->getScore();
          }
        }
        else {
          $course_modules = opigno_learning_path_get_course_modules($module
            ->id());
          foreach ($course_modules as $step_id => $course_module) {
            if (in_array($course_module
              ->getKeepResultsOption(), [
              'newest',
              'all',
            ])) {
              if (!empty($last_attempts[$step_id])) {
                $user_scores[$step_id] = $last_attempts[$step_id]
                  ->getScore();
              }
              if (empty($user_scores[$step_id])) {
                $user_scores[$step_id] = 0;
              }
            }
          }
        }
      }
    }

    // Check required conditions only for those
    // trainings which have guided navigation option on.
    if (isset($guidedNavigation) && $guidedNavigation) {

      // Check required conditions.
      foreach ($required_conditions as $required_condition) {
        $required_activities = $required_condition->required_activities ? unserialize($required_condition->required_activities) : NULL;
        $required_score = $required_condition->required_score;

        // Required score depending to module last attempt.
        $check_required_activities = TRUE;
        if ($required_score && $user_score < $required_score) {
          $no_conditions_met = TRUE;
          $next_step_id = NULL;
          $check_required_activities = FALSE;
        }

        // Check required activities if they were set.
        if ($check_required_activities && $required_activities && $last_attempts) {
          $successful_activities = $this
            ->getSuccessfulRequiredActvities($required_activities, $last_attempts);
          if ($successful_activities) {
            $success = TRUE;
            foreach ($required_activities as $required_activity) {
              if (!in_array($required_activity, $successful_activities)) {
                $success = FALSE;
                break;
              }
            }
            if ($success && count($required_activities) == count($successful_activities)) {

              // Set next step if all required activities were successful.
              $next_step_id = $required_condition->id;
              $no_conditions_met = FALSE;
              break;
            }
          }
        }
      }
    }
    if ($no_conditions_met) {

      // If no conditions met check for
      // activities without required conditions.
      $no_required_free = TRUE;
      foreach ($required_conditions as $required_condition) {
        if ($required_condition->required_score == '0' && empty($required_condition->required_activities)) {
          $next_step_id = $required_condition->id;
          $no_required_free = FALSE;
          break;
        }
      }

      // No activities without required conditions found.
      if ($no_required_free) {
        $next_step_id = NULL;
        $_SESSION['step_required_conditions_failed'] = TRUE;
      }
    }
  }
  if (!empty($next_step_id)) {

    // If a result is found, return the next content object.
    $next_step_link = OpignoGroupManagedLink::load($next_step_id);
    if ($next_step_link) {
      return $next_step_link
        ->getChildContent();
    }
  }
  return FALSE;
}