You are here

public function CourseObject::access in Course 6

Same name and namespace in other branches
  1. 7.2 includes/CourseObject.inc \CourseObject::access()
  2. 7 includes/CourseObject.inc \CourseObject::access()

Access functionality for course objects.

Possible values for $op are 'see', 'view', 'take'.

"see" means see it in a course outline. For example, a conditional survey should not be seen in the course outline. A quiz at the end of the course, should show up, but the user must not be able to take it.

"view" means view and interact with the object, but nothing would be recorded. For example, accessing a quiz but not being able to submit responses.

"take" means interact with the object in a way that records data.

Subclasses may override this functionality.

1 call to CourseObject::access()
CourseObject::takeCourseObject in includes/course_object.core.inc
Take a course object.

File

includes/course_object.core.inc, line 106

Class

CourseObject
Parent abstract base class of all course objects.

Code

public function access($op = 'view', $account = NULL) {
  ctools_include('plugins');
  $access = FALSE;
  if (!$account) {
    global $user;
    $account = $user;
  }

  // Stock access: check for completion of previous object.
  switch ($op) {
    case 'see':
      $access = !$this
        ->getOption('hidden') && $this
        ->getOption('enabled');
      break;
    case 'take':
      if (!$account->uid) {
        return FALSE;
      }
    case 'view':

      // Get a copy of the course, so we can run setActive() without changing
      // the global course.
      $course = clone $this
        ->getCourse();
      $course
        ->setActive($this
        ->getId());
      $courseObjects = $course
        ->getObjects();
      if ($courseObjects && $courseObjects[0]
        ->getId() == $this
        ->getId()) {

        // This is the first course object. The learner should be able to
        // access it. Also, check for enrollment. Since there are no other
        // checks (as in previous object completions) we do have to check this.
        $access = course_enrolment_check($this
          ->getCourseNid(), $account->uid);
      }
      if ($course
        ->getPrev() && !$course
        ->getPrev()
        ->isRequired()) {

        // Previous step was not required.
        $access = TRUE;

        // But we need to see if at least one required step was completed (or the start of the course).
        $objects = array_reverse($course
          ->getObjects());
        $check = FALSE;
        foreach ($objects as $object) {
          if ($check) {
            if ($object
              ->isRequired()) {

              // Object is required.
              if (!$object
                ->getFulfillment()
                ->isComplete()) {

                // Found a required object that was not complete.
                $access = FALSE;
                break;
              }
              else {

                // The last required object was completed.
                $access = TRUE;
                break;
              }
            }
          }
          if ($object
            ->getId() == $this
            ->getId()) {

            // We found the object we are trying to check access on.
            // Now we want to go backwards.
            $check = 1;
          }
        }
      }
      if ($course
        ->getPrev() && $course
        ->getPrev()
        ->getFulfillment()
        ->isComplete()) {

        // If last object was complete, and we are on the current object,
        // grant access.
        $access = TRUE;
      }
  }

  // Plugin access.
  foreach (ctools_get_plugins('course', 'access') as $key => $plugin) {
    $class = ctools_plugin_get_class($plugin, 'handler');
    $accessPluginDefaults = array();
    if (isset($this->config['plugins']['access'][$key])) {
      $accessPluginDefaults = (array) $this->config['plugins']['access'][$key];
    }
    $accessPlugin = new $class();
    if ($accessPluginDefaults) {
      $accessPlugin
        ->setOptions($accessPluginDefaults);
    }
    $accessPlugin
      ->setCourseObject($this);

    // Run access check.
    $ret = $accessPlugin
      ->{$op}();
    if ($ret === FALSE) {

      // If previous access was granted, revoke it.
      $access = $ret;
    }
  }
  return $access;
}