/**
  *  Checks if the exercise is visible due a lot of conditions - visibility, time limits, student attempts
  * @return bool true if is active
  */
 public function is_visible($lp_id = 0, $lp_item_id = 0, $lp_item_view_id = 0, $filter_by_admin = true)
 {
     // 1. By default the exercise is visible
     $is_visible = true;
     $message = null;
     // 1.1 Admins and teachers can access to the exercise
     if ($filter_by_admin) {
         if (api_is_platform_admin() || api_is_course_admin()) {
             return array('value' => true, 'message' => '');
         }
     }
     // Deleted exercise.
     if ($this->active == -1) {
         return array('value' => false, 'message' => Display::return_message(get_lang('ExerciseNotFound'), 'warning', false));
     }
     // Checking visibility in the item_property table.
     $visibility = api_get_item_visibility(api_get_course_info(), TOOL_QUIZ, $this->id, api_get_session_id());
     if ($visibility == 0 || $visibility == 2) {
         $this->active = 0;
     }
     // 2. If the exercise is not active.
     if (empty($lp_id)) {
         // 2.1 LP is OFF
         if ($this->active == 0) {
             return array('value' => false, 'message' => Display::return_message(get_lang('ExerciseNotFound'), 'warning', false));
         }
     } else {
         // 2.1 LP is loaded
         if ($this->active == 0 && !learnpath::is_lp_visible_for_student($lp_id, api_get_user_id())) {
             return array('value' => false, 'message' => Display::return_message(get_lang('ExerciseNotFound'), 'warning', false));
         }
     }
     //3. We check if the time limits are on
     $limit_time_exists = !empty($this->start_time) && $this->start_time != '0000-00-00 00:00:00' || !empty($this->end_time) && $this->end_time != '0000-00-00 00:00:00' ? true : false;
     if ($limit_time_exists) {
         $time_now = time();
         if (!empty($this->start_time) && $this->start_time != '0000-00-00 00:00:00') {
             $is_visible = $time_now - api_strtotime($this->start_time, 'UTC') > 0 ? true : false;
         }
         if ($is_visible == false) {
             $message = sprintf(get_lang('ExerciseAvailableFromX'), api_convert_and_format_date($this->start_time));
         }
         if ($is_visible == true) {
             if ($this->end_time != '0000-00-00 00:00:00') {
                 $is_visible = (api_strtotime($this->end_time, 'UTC') > $time_now) > 0 ? true : false;
                 if ($is_visible == false) {
                     $message = sprintf(get_lang('ExerciseAvailableUntilX'), api_convert_and_format_date($this->end_time));
                 }
             }
         }
         if ($is_visible == false && $this->start_time != '0000-00-00 00:00:00' && $this->end_time != '0000-00-00 00:00:00') {
             $message = sprintf(get_lang('ExerciseWillBeActivatedFromXToY'), api_convert_and_format_date($this->start_time), api_convert_and_format_date($this->end_time));
         }
     }
     // 4. We check if the student have attempts
     $exerciseAttempts = $this->selectAttempts();
     if ($is_visible) {
         if ($exerciseAttempts > 0) {
             $attempt_count = Event::get_attempt_count_not_finished(api_get_user_id(), $this->id, $lp_id, $lp_item_id, $lp_item_view_id);
             if ($attempt_count >= $exerciseAttempts) {
                 $message = sprintf(get_lang('ReachedMaxAttempts'), $this->name, $exerciseAttempts);
                 $is_visible = false;
             }
         }
     }
     if (!empty($message)) {
         $message = Display::return_message($message, 'warning', false);
     }
     return array('value' => $is_visible, 'message' => $message);
 }
 /**
  * Checks if the exercise is visible due a lot of conditions
  * visibility, time limits, student attempts
  * Return associative array
  * value : true if execise visible
  * message : HTML formated message
  * rawMessage : text message
  * @param int $lpId
  * @param int $lpItemId
  * @param int $lpItemViewId
  * @param bool $filterByAdmin
  * @return array
  */
 public function is_visible($lpId = 0, $lpItemId = 0, $lpItemViewId = 0, $filterByAdmin = true)
 {
     // 1. By default the exercise is visible
     $is_visible = true;
     $message = null;
     // 1.1 Admins and teachers can access to the exercise
     if ($filterByAdmin) {
         if (api_is_platform_admin() || api_is_course_admin()) {
             return array('value' => true, 'message' => '');
         }
     }
     // Deleted exercise.
     if ($this->active == -1) {
         return array('value' => false, 'message' => Display::return_message(get_lang('ExerciseNotFound'), 'warning', false), 'rawMessage' => get_lang('ExerciseNotFound'));
     }
     // Checking visibility in the item_property table.
     $visibility = api_get_item_visibility(api_get_course_info(), TOOL_QUIZ, $this->id, api_get_session_id());
     if ($visibility == 0 || $visibility == 2) {
         $this->active = 0;
     }
     // 2. If the exercise is not active.
     if (empty($lpId)) {
         // 2.1 LP is OFF
         if ($this->active == 0) {
             return array('value' => false, 'message' => Display::return_message(get_lang('ExerciseNotFound'), 'warning', false), 'rawMessage' => get_lang('ExerciseNotFound'));
         }
     } else {
         // 2.1 LP is loaded
         if ($this->active == 0 && !learnpath::is_lp_visible_for_student($lpId, api_get_user_id())) {
             return array('value' => false, 'message' => Display::return_message(get_lang('ExerciseNotFound'), 'warning', false), 'rawMessage' => get_lang('ExerciseNotFound'));
         }
     }
     //3. We check if the time limits are on
     if (!empty($this->start_time) && $this->start_time != '0000-00-00 00:00:00' || !empty($this->end_time) && $this->end_time != '0000-00-00 00:00:00') {
         $limitTimeExists = true;
     } else {
         $limitTimeExists = false;
     }
     if ($limitTimeExists) {
         $timeNow = time();
         $existsStartDate = false;
         $nowIsAfterStartDate = true;
         $existsEndDate = false;
         $nowIsBeforeEndDate = true;
         if (!empty($this->start_time) && $this->start_time != '0000-00-00 00:00:00') {
             $existsStartDate = true;
         }
         if (!empty($this->end_time) && $this->end_time != '0000-00-00 00:00:00') {
             $existsEndDate = true;
         }
         // check if we are before-or-after end-or-start date
         if ($existsStartDate && $timeNow < api_strtotime($this->start_time, 'UTC')) {
             $nowIsAfterStartDate = false;
         }
         if ($existsEndDate & $timeNow >= api_strtotime($this->end_time, 'UTC')) {
             $nowIsBeforeEndDate = false;
         }
         // lets check all cases
         if ($existsStartDate && !$existsEndDate) {
             // exists start date and dont exists end date
             if ($nowIsAfterStartDate) {
                 // after start date, no end date
                 $isVisible = true;
                 $message = sprintf(get_lang('ExerciseAvailableSinceX'), api_convert_and_format_date($this->start_time));
             } else {
                 // before start date, no end date
                 $isVisible = false;
                 $message = sprintf(get_lang('ExerciseAvailableFromX'), api_convert_and_format_date($this->start_time));
             }
         } else {
             if (!$existsStartDate && $existsEndDate) {
                 // doesnt exist start date, exists end date
                 if ($nowIsBeforeEndDate) {
                     // before end date, no start date
                     $isVisible = true;
                     $message = sprintf(get_lang('ExerciseAvailableUntilX'), api_convert_and_format_date($this->end_time));
                 } else {
                     // after end date, no start date
                     $isVisible = false;
                     $message = sprintf(get_lang('ExerciseAvailableUntilX'), api_convert_and_format_date($this->end_time));
                 }
             } elseif ($existsStartDate && $existsEndDate) {
                 // exists start date and end date
                 if ($nowIsAfterStartDate) {
                     if ($nowIsBeforeEndDate) {
                         // after start date and before end date
                         $isVisible = true;
                         $message = sprintf(get_lang('ExerciseIsActivatedFromXToY'), api_convert_and_format_date($this->start_time), api_convert_and_format_date($this->end_time));
                     } else {
                         // after start date and after end date
                         $isVisible = false;
                         $message = sprintf(get_lang('ExerciseWasActivatedFromXToY'), api_convert_and_format_date($this->start_time), api_convert_and_format_date($this->end_time));
                     }
                 } else {
                     if ($nowIsBeforeEndDate) {
                         // before start date and before end date
                         $isVisible = false;
                         $message = sprintf(get_lang('ExerciseWillBeActivatedFromXToY'), api_convert_and_format_date($this->start_time), api_convert_and_format_date($this->end_time));
                     }
                     // case before start date and after end date is impossible
                 }
             } elseif (!$existsStartDate && !$existsEndDate) {
                 // doesnt exist start date nor end date
                 $isVisible = true;
                 $message = "";
             }
         }
     }
     // 4. We check if the student have attempts
     $exerciseAttempts = $this->selectAttempts();
     if ($isVisible) {
         if ($exerciseAttempts > 0) {
             $attemptCount = Event::get_attempt_count_not_finished(api_get_user_id(), $this->id, $lpId, $lpItemId, $lpItemViewId);
             if ($attemptCount >= $exerciseAttempts) {
                 $message = sprintf(get_lang('ReachedMaxAttempts'), $this->name, $exerciseAttempts);
                 $isVisible = false;
             }
         }
     }
     $rawMessage = "";
     if (!empty($message)) {
         $rawMessage = $message;
         $message = Display::return_message($message, 'warning', false);
     }
     return array('value' => $isVisible, 'message' => $message, 'rawMessage' => $rawMessage);
 }