Example #1
0
/**
 * Return time options, which should be shown for record filtering.
 *
 * @param int $minlog Time of first log record available.
 * @return array time options.
 */
function report_participation_get_time_options($minlog)
{
    $timeoptions = array();
    $now = usergetmidnight(time());
    // Days.
    for ($i = 1; $i < 7; $i++) {
        if (strtotime('-' . $i . ' days', $now) >= $minlog) {
            $timeoptions[strtotime('-' . $i . ' days', $now)] = get_string('numdays', 'moodle', $i);
        }
    }
    // Weeks.
    for ($i = 1; $i < 10; $i++) {
        if (strtotime('-' . $i . ' weeks', $now) >= $minlog) {
            $timeoptions[strtotime('-' . $i . ' weeks', $now)] = get_string('numweeks', 'moodle', $i);
        }
    }
    // Months.
    for ($i = 2; $i < 12; $i++) {
        if (strtotime('-' . $i . ' months', $now) >= $minlog) {
            $timeoptions[strtotime('-' . $i . ' months', $now)] = get_string('nummonths', 'moodle', $i);
        }
    }
    // Try a year.
    if (strtotime('-1 year', $now) >= $minlog) {
        $timeoptions[strtotime('-1 year', $now)] = get_string('lastyear');
    }
    return $timeoptions;
}
Example #2
0
File: lib.php Project: rrusso/EARS
 function __construct($script, $value, $params, $extra)
 {
     $this->key = 'date_referred';
     $this->value = $this->get_value_or_default($value);
     $this->params = $params;
     $this->script = $script;
     $this->now = usergetmidnight(time()) + 60 * 60 * 23 + 3599;
 }
    function get_all_elements() {
        $elements = array();

        $components = cr_unserialize($this->config->components);

        $config = (isset($components['timeline']['config'])) ? $components['timeline']['config'] : new stdclass();

        if (isset($config->timemode)) {

            $daysecs = 60 * 60 * 24;

            if ($config->timemode == 'previous') {
                $config->starttime = gmmktime() - $config->previousstart * $daysecs;
                $config->endtime = gmmktime() - $config->previousend * $daysecs;
                if (isset($config->forcemidnight)) {
                    $config->starttime = usergetmidnight($config->starttime);
                    $config->endtime = usergetmidnight($config->endtime) + ($daysecs - 1);
                }
            }

            $filter_starttime = optional_param('filter_starttime', 0, PARAM_RAW);
            $filter_endtime = optional_param('filter_endtime', 0, PARAM_RAW);

            if ($filter_starttime and $filter_endtime) {
                $filter_starttime = make_timestamp($filter_starttime['year'], $filter_starttime['month'], $filter_starttime['day']);
                $filter_endtime = make_timestamp($filter_endtime['year'], $filter_endtime['month'], $filter_endtime['day']);

                $config->starttime = usergetmidnight($filter_starttime);
                $config->endtime = usergetmidnight($filter_endtime) + 24 * 60 * 60;
            }


            for ($i = $config->starttime; $i < $config->endtime; $i += $config->interval * $daysecs) {
                $row = new stdclass();
                $row->id = $i;
                $row->starttime = $i;
                $row->endtime = $row->starttime + ($config->interval * $daysecs - 1);
                if ($row->endtime > $config->endtime)
                    $row->endtime = $config->endtime;
                $this->timeline[$row->starttime] = $row;
                $elements[] = $row->starttime;
            }

            if ($config->ordering == 'desc')
                rsort($elements);
        }

        return $elements;
    }
Example #4
0
if (!isset($hiddenfields['lastaccess'])) {
    // Get minimum lastaccess for this course and display a dropbox to filter by lastaccess going back this far.
    // We need to make it diferently for normal courses and site course.
    if (!$isfrontpage) {
        $minlastaccess = $DB->get_field_sql('SELECT min(timeaccess)
                                               FROM {user_lastaccess}
                                              WHERE courseid = ?
                                                    AND timeaccess != 0', array($course->id));
        $lastaccess0exists = $DB->record_exists('user_lastaccess', array('courseid' => $course->id, 'timeaccess' => 0));
    } else {
        $minlastaccess = $DB->get_field_sql('SELECT min(lastaccess)
                                               FROM {user}
                                              WHERE lastaccess != 0');
        $lastaccess0exists = $DB->record_exists('user', array('lastaccess' => 0));
    }
    $now = usergetmidnight(time());
    $timeaccess = array();
    $baseurl->remove_params('accesssince');
    // Makes sense for this to go first.
    $timeoptions[0] = get_string('selectperiod');
    // Days.
    for ($i = 1; $i < 7; $i++) {
        if (strtotime('-' . $i . ' days', $now) >= $minlastaccess) {
            $timeoptions[strtotime('-' . $i . ' days', $now)] = get_string('numdays', 'moodle', $i);
        }
    }
    // Weeks.
    for ($i = 1; $i < 10; $i++) {
        if (strtotime('-' . $i . ' weeks', $now) >= $minlastaccess) {
            $timeoptions[strtotime('-' . $i . ' weeks', $now)] = get_string('numweeks', 'moodle', $i);
        }
Example #5
0
     if (empty($CFG->grade_profilereport) or !file_exists($CFG->dirroot . '/grade/report/' . $CFG->grade_profilereport . '/lib.php')) {
         $CFG->grade_profilereport = 'user';
     }
     require_once $CFG->libdir . '/gradelib.php';
     require_once $CFG->dirroot . '/grade/lib.php';
     require_once $CFG->dirroot . '/grade/report/' . $CFG->grade_profilereport . '/lib.php';
     $functionname = 'grade_report_' . $CFG->grade_profilereport . '_profilereport';
     if (function_exists($functionname)) {
         $functionname($course, $user);
     }
     break;
 case "todaylogs":
     echo '<div class="graph">';
     print_log_graph($course, $user->id, "userday.png");
     echo '</div>';
     print_log($course, $user->id, usergetmidnight(time()), "l.time DESC", $page, $perpage, "user.php?id={$course->id}&amp;user={$user->id}&amp;mode={$mode}");
     break;
 case "alllogs":
     echo '<div class="graph">';
     print_log_graph($course, $user->id, "usercourse.png");
     echo '</div>';
     print_log($course, $user->id, 0, "l.time DESC", $page, $perpage, "user.php?id={$course->id}&amp;user={$user->id}&amp;mode={$mode}");
     break;
 case 'stats':
     if (empty($CFG->enablestats)) {
         error("Stats is not enabled.");
     }
     require_once $CFG->dirroot . '/lib/statslib.php';
     $statsstatus = stats_check_uptodate($course->id);
     if ($statsstatus !== NULL) {
         notify($statsstatus);
 function instance_config_print()
 {
     global $CFG, $DB;
     if (!isset($this->config)) {
         // ... teacher has not yet configured the block, let's put some default values here to explain things
         $this->config->title = get_string('blockname', 'block_glossary_random');
         $this->config->refresh = 0;
         $this->config->showconcept = 1;
         $this->config->cache = get_string('notyetconfigured', 'block_glossary_random');
         $this->config->addentry = get_string('addentry', 'block_glossary_random');
         $this->config->viewglossary = get_string('viewglossary', 'block_glossary_random');
         $this->config->invisible = get_string('invisible', 'block_glossary_random');
     }
     // select glossaries to put in dropdown box ...
     $glossaries = $DB->get_records_menu('glossary', array('course' => $this->course->id), 'name', 'id,name');
     //format menu texts to avoid html and to filter multilang values
     if (!empty($glossaries)) {
         foreach ($glossaries as $key => $value) {
             $glossaries[$key] = strip_tags(format_string($value, true));
         }
     }
     // and select quotetypes to put in dropdown box
     $type[0] = get_string('random', 'block_glossary_random');
     $type[1] = get_string('lastmodified', 'block_glossary_random');
     $type[2] = get_string('nextone', 'block_glossary_random');
     $this->config->nexttime = usergetmidnight(time()) + DAYSECS * $this->config->refresh;
     // display the form
     if (is_file($CFG->dirroot . '/blocks/' . $this->name() . '/config_instance.html')) {
         print_simple_box_start('center', '', '', 5, 'blockconfigglobal');
         include $CFG->dirroot . '/blocks/' . $this->name() . '/config_instance.html';
         print_simple_box_end();
     } else {
         notice(get_string('blockconfigbad'), str_replace('blockaction=', 'dummy=', qualified_me()));
     }
     return true;
 }
Example #7
0
    $graph->parameter['tick_length'] = 0;
    $graph->parameter['shadow'] = 'none';
    error_reporting(5);
    // Ignore most warnings such as font problems etc.
    $graph->draw_stack();
} else {
    $site = get_site();
    if ($course->id == $site->id) {
        $courseselect = 0;
    } else {
        $courseselect = $course->id;
    }
    if ($date) {
        $daystart = usergetmidnight($date);
    } else {
        $daystart = usergetmidnight(time());
    }
    $dayfinish = $daystart + 86400;
    $hours = array();
    for ($i = 0; $i <= 23; $i++) {
        $logs[$i] = 0;
        $hour = $daystart + $i * 3600;
        $hours[$i] = $i;
    }
    $rawlogs = report_log_userday($user->id, $courseselect, $daystart, $logreader);
    if (empty($rawlogs)) {
        return;
    }
    foreach ($rawlogs as $rawlog) {
        $logs[$rawlog->hour] = $rawlog->num;
    }
Example #8
0
/**
 * Function to be run periodically according to the scheduled task.
 *
 * Finds all posts that have yet to be mailed out, and mails them
 * out to all subscribers as well as other maintance tasks.
 *
 * NOTE: Since 2.7.2 this function is run by scheduled task rather
 * than standard cron.
 *
 * @todo MDL-44734 The function will be split up into seperate tasks.
 */
function forum_cron()
{
    global $CFG, $USER, $DB, $PAGE;
    $site = get_site();
    // The main renderers.
    $htmlout = $PAGE->get_renderer('mod_forum', 'email', 'htmlemail');
    $textout = $PAGE->get_renderer('mod_forum', 'email', 'textemail');
    $htmldigestfullout = $PAGE->get_renderer('mod_forum', 'emaildigestfull', 'htmlemail');
    $textdigestfullout = $PAGE->get_renderer('mod_forum', 'emaildigestfull', 'textemail');
    $htmldigestbasicout = $PAGE->get_renderer('mod_forum', 'emaildigestbasic', 'htmlemail');
    $textdigestbasicout = $PAGE->get_renderer('mod_forum', 'emaildigestbasic', 'textemail');
    // All users that are subscribed to any post that needs sending,
    // please increase $CFG->extramemorylimit on large sites that
    // send notifications to a large number of users.
    $users = array();
    $userscount = 0;
    // Cached user counter - count($users) in PHP is horribly slow!!!
    // Status arrays.
    $mailcount = array();
    $errorcount = array();
    // caches
    $discussions = array();
    $forums = array();
    $courses = array();
    $coursemodules = array();
    $subscribedusers = array();
    $messageinboundhandlers = array();
    // Posts older than 2 days will not be mailed.  This is to avoid the problem where
    // cron has not been running for a long time, and then suddenly people are flooded
    // with mail from the past few weeks or months
    $timenow = time();
    $endtime = $timenow - $CFG->maxeditingtime;
    $starttime = $endtime - 48 * 3600;
    // Two days earlier
    // Get the list of forum subscriptions for per-user per-forum maildigest settings.
    $digestsset = $DB->get_recordset('forum_digests', null, '', 'id, userid, forum, maildigest');
    $digests = array();
    foreach ($digestsset as $thisrow) {
        if (!isset($digests[$thisrow->forum])) {
            $digests[$thisrow->forum] = array();
        }
        $digests[$thisrow->forum][$thisrow->userid] = $thisrow->maildigest;
    }
    $digestsset->close();
    // Create the generic messageinboundgenerator.
    $messageinboundgenerator = new \core\message\inbound\address_manager();
    $messageinboundgenerator->set_handler('\\mod_forum\\message\\inbound\\reply_handler');
    if ($posts = forum_get_unmailed_posts($starttime, $endtime, $timenow)) {
        // Mark them all now as being mailed.  It's unlikely but possible there
        // might be an error later so that a post is NOT actually mailed out,
        // but since mail isn't crucial, we can accept this risk.  Doing it now
        // prevents the risk of duplicated mails, which is a worse problem.
        if (!forum_mark_old_posts_as_mailed($endtime)) {
            mtrace('Errors occurred while trying to mark some posts as being mailed.');
            return false;
            // Don't continue trying to mail them, in case we are in a cron loop
        }
        // checking post validity, and adding users to loop through later
        foreach ($posts as $pid => $post) {
            $discussionid = $post->discussion;
            if (!isset($discussions[$discussionid])) {
                if ($discussion = $DB->get_record('forum_discussions', array('id' => $post->discussion))) {
                    $discussions[$discussionid] = $discussion;
                    \mod_forum\subscriptions::fill_subscription_cache($discussion->forum);
                    \mod_forum\subscriptions::fill_discussion_subscription_cache($discussion->forum);
                } else {
                    mtrace('Could not find discussion ' . $discussionid);
                    unset($posts[$pid]);
                    continue;
                }
            }
            $forumid = $discussions[$discussionid]->forum;
            if (!isset($forums[$forumid])) {
                if ($forum = $DB->get_record('forum', array('id' => $forumid))) {
                    $forums[$forumid] = $forum;
                } else {
                    mtrace('Could not find forum ' . $forumid);
                    unset($posts[$pid]);
                    continue;
                }
            }
            $courseid = $forums[$forumid]->course;
            if (!isset($courses[$courseid])) {
                if ($course = $DB->get_record('course', array('id' => $courseid))) {
                    $courses[$courseid] = $course;
                } else {
                    mtrace('Could not find course ' . $courseid);
                    unset($posts[$pid]);
                    continue;
                }
            }
            if (!isset($coursemodules[$forumid])) {
                if ($cm = get_coursemodule_from_instance('forum', $forumid, $courseid)) {
                    $coursemodules[$forumid] = $cm;
                } else {
                    mtrace('Could not find course module for forum ' . $forumid);
                    unset($posts[$pid]);
                    continue;
                }
            }
            // Save the Inbound Message datakey here to reduce DB queries later.
            $messageinboundgenerator->set_data($pid);
            $messageinboundhandlers[$pid] = $messageinboundgenerator->fetch_data_key();
            // Caching subscribed users of each forum.
            if (!isset($subscribedusers[$forumid])) {
                $modcontext = context_module::instance($coursemodules[$forumid]->id);
                if ($subusers = \mod_forum\subscriptions::fetch_subscribed_users($forums[$forumid], 0, $modcontext, 'u.*', true)) {
                    foreach ($subusers as $postuser) {
                        // this user is subscribed to this forum
                        $subscribedusers[$forumid][$postuser->id] = $postuser->id;
                        $userscount++;
                        if ($userscount > FORUM_CRON_USER_CACHE) {
                            // Store minimal user info.
                            $minuser = new stdClass();
                            $minuser->id = $postuser->id;
                            $users[$postuser->id] = $minuser;
                        } else {
                            // Cache full user record.
                            forum_cron_minimise_user_record($postuser);
                            $users[$postuser->id] = $postuser;
                        }
                    }
                    // Release memory.
                    unset($subusers);
                    unset($postuser);
                }
            }
            $mailcount[$pid] = 0;
            $errorcount[$pid] = 0;
        }
    }
    if ($users && $posts) {
        foreach ($users as $userto) {
            // Terminate if processing of any account takes longer than 2 minutes.
            core_php_time_limit::raise(120);
            mtrace('Processing user ' . $userto->id);
            // Init user caches - we keep the cache for one cycle only, otherwise it could consume too much memory.
            if (isset($userto->username)) {
                $userto = clone $userto;
            } else {
                $userto = $DB->get_record('user', array('id' => $userto->id));
                forum_cron_minimise_user_record($userto);
            }
            $userto->viewfullnames = array();
            $userto->canpost = array();
            $userto->markposts = array();
            // Setup this user so that the capabilities are cached, and environment matches receiving user.
            cron_setup_user($userto);
            // Reset the caches.
            foreach ($coursemodules as $forumid => $unused) {
                $coursemodules[$forumid]->cache = new stdClass();
                $coursemodules[$forumid]->cache->caps = array();
                unset($coursemodules[$forumid]->uservisible);
            }
            foreach ($posts as $pid => $post) {
                $discussion = $discussions[$post->discussion];
                $forum = $forums[$discussion->forum];
                $course = $courses[$forum->course];
                $cm =& $coursemodules[$forum->id];
                // Do some checks to see if we can bail out now.
                // Only active enrolled users are in the list of subscribers.
                // This does not necessarily mean that the user is subscribed to the forum or to the discussion though.
                if (!isset($subscribedusers[$forum->id][$userto->id])) {
                    // The user does not subscribe to this forum.
                    continue;
                }
                if (!\mod_forum\subscriptions::is_subscribed($userto->id, $forum, $post->discussion, $coursemodules[$forum->id])) {
                    // The user does not subscribe to this forum, or to this specific discussion.
                    continue;
                }
                if ($subscriptiontime = \mod_forum\subscriptions::fetch_discussion_subscription($forum->id, $userto->id)) {
                    // Skip posts if the user subscribed to the discussion after it was created.
                    if (isset($subscriptiontime[$post->discussion]) && $subscriptiontime[$post->discussion] > $post->created) {
                        continue;
                    }
                }
                // Don't send email if the forum is Q&A and the user has not posted.
                // Initial topics are still mailed.
                if ($forum->type == 'qanda' && !forum_get_user_posted_time($discussion->id, $userto->id) && $pid != $discussion->firstpost) {
                    mtrace('Did not email ' . $userto->id . ' because user has not posted in discussion');
                    continue;
                }
                // Get info about the sending user.
                if (array_key_exists($post->userid, $users)) {
                    // We might know the user already.
                    $userfrom = $users[$post->userid];
                    if (!isset($userfrom->idnumber)) {
                        // Minimalised user info, fetch full record.
                        $userfrom = $DB->get_record('user', array('id' => $userfrom->id));
                        forum_cron_minimise_user_record($userfrom);
                    }
                } else {
                    if ($userfrom = $DB->get_record('user', array('id' => $post->userid))) {
                        forum_cron_minimise_user_record($userfrom);
                        // Fetch only once if possible, we can add it to user list, it will be skipped anyway.
                        if ($userscount <= FORUM_CRON_USER_CACHE) {
                            $userscount++;
                            $users[$userfrom->id] = $userfrom;
                        }
                    } else {
                        mtrace('Could not find user ' . $post->userid . ', author of post ' . $post->id . '. Unable to send message.');
                        continue;
                    }
                }
                // Note: If we want to check that userto and userfrom are not the same person this is probably the spot to do it.
                // Setup global $COURSE properly - needed for roles and languages.
                cron_setup_user($userto, $course);
                // Fill caches.
                if (!isset($userto->viewfullnames[$forum->id])) {
                    $modcontext = context_module::instance($cm->id);
                    $userto->viewfullnames[$forum->id] = has_capability('moodle/site:viewfullnames', $modcontext);
                }
                if (!isset($userto->canpost[$discussion->id])) {
                    $modcontext = context_module::instance($cm->id);
                    $userto->canpost[$discussion->id] = forum_user_can_post($forum, $discussion, $userto, $cm, $course, $modcontext);
                }
                if (!isset($userfrom->groups[$forum->id])) {
                    if (!isset($userfrom->groups)) {
                        $userfrom->groups = array();
                        if (isset($users[$userfrom->id])) {
                            $users[$userfrom->id]->groups = array();
                        }
                    }
                    $userfrom->groups[$forum->id] = groups_get_all_groups($course->id, $userfrom->id, $cm->groupingid);
                    if (isset($users[$userfrom->id])) {
                        $users[$userfrom->id]->groups[$forum->id] = $userfrom->groups[$forum->id];
                    }
                }
                // Make sure groups allow this user to see this email.
                if ($discussion->groupid > 0 and $groupmode = groups_get_activity_groupmode($cm, $course)) {
                    // Groups are being used.
                    if (!groups_group_exists($discussion->groupid)) {
                        // Can't find group - be safe and don't this message.
                        continue;
                    }
                    if (!groups_is_member($discussion->groupid) and !has_capability('moodle/site:accessallgroups', $modcontext)) {
                        // Do not send posts from other groups when in SEPARATEGROUPS or VISIBLEGROUPS.
                        continue;
                    }
                }
                // Make sure we're allowed to see the post.
                if (!forum_user_can_see_post($forum, $discussion, $post, null, $cm)) {
                    mtrace('User ' . $userto->id . ' can not see ' . $post->id . '. Not sending message.');
                    continue;
                }
                // OK so we need to send the email.
                // Does the user want this post in a digest?  If so postpone it for now.
                $maildigest = forum_get_user_maildigest_bulk($digests, $userto, $forum->id);
                if ($maildigest > 0) {
                    // This user wants the mails to be in digest form.
                    $queue = new stdClass();
                    $queue->userid = $userto->id;
                    $queue->discussionid = $discussion->id;
                    $queue->postid = $post->id;
                    $queue->timemodified = $post->created;
                    $DB->insert_record('forum_queue', $queue);
                    continue;
                }
                // Prepare to actually send the post now, and build up the content.
                $cleanforumname = str_replace('"', "'", strip_tags(format_string($forum->name)));
                $userfrom->customheaders = array('List-Id: "' . $cleanforumname . '" ' . generate_email_messageid('moodleforum' . $forum->id), 'List-Help: ' . $CFG->wwwroot . '/mod/forum/view.php?f=' . $forum->id, 'Message-ID: ' . forum_get_email_message_id($post->id, $userto->id), 'X-Course-Id: ' . $course->id, 'X-Course-Name: ' . format_string($course->fullname, true), 'Precedence: Bulk', 'X-Auto-Response-Suppress: All', 'Auto-Submitted: auto-generated');
                $shortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
                // Generate a reply-to address from using the Inbound Message handler.
                $replyaddress = null;
                if ($userto->canpost[$discussion->id] && array_key_exists($post->id, $messageinboundhandlers)) {
                    $messageinboundgenerator->set_data($post->id, $messageinboundhandlers[$post->id]);
                    $replyaddress = $messageinboundgenerator->generate($userto->id);
                }
                if (!isset($userto->canpost[$discussion->id])) {
                    $canreply = forum_user_can_post($forum, $discussion, $userto, $cm, $course, $modcontext);
                } else {
                    $canreply = $userto->canpost[$discussion->id];
                }
                $data = new \mod_forum\output\forum_post_email($course, $cm, $forum, $discussion, $post, $userfrom, $userto, $canreply);
                $userfrom->customheaders[] = sprintf('List-Unsubscribe: <%s>', $data->get_unsubscribediscussionlink());
                if (!isset($userto->viewfullnames[$forum->id])) {
                    $data->viewfullnames = has_capability('moodle/site:viewfullnames', $modcontext, $userto->id);
                } else {
                    $data->viewfullnames = $userto->viewfullnames[$forum->id];
                }
                // Not all of these variables are used in the default language
                // string but are made available to support custom subjects.
                $a = new stdClass();
                $a->subject = $data->get_subject();
                $a->forumname = $cleanforumname;
                $a->sitefullname = format_string($site->fullname);
                $a->siteshortname = format_string($site->shortname);
                $a->courseidnumber = $data->get_courseidnumber();
                $a->coursefullname = $data->get_coursefullname();
                $a->courseshortname = $data->get_coursename();
                $postsubject = html_to_text(get_string('postmailsubject', 'forum', $a), 0);
                $rootid = forum_get_email_message_id($discussion->firstpost, $userto->id);
                if ($post->parent) {
                    // This post is a reply, so add reply header (RFC 2822).
                    $parentid = forum_get_email_message_id($post->parent, $userto->id);
                    $userfrom->customheaders[] = "In-Reply-To: {$parentid}";
                    // If the post is deeply nested we also reference the parent message id and
                    // the root message id (if different) to aid threading when parts of the email
                    // conversation have been deleted (RFC1036).
                    if ($post->parent != $discussion->firstpost) {
                        $userfrom->customheaders[] = "References: {$rootid} {$parentid}";
                    } else {
                        $userfrom->customheaders[] = "References: {$parentid}";
                    }
                }
                // MS Outlook / Office uses poorly documented and non standard headers, including
                // Thread-Topic which overrides the Subject and shouldn't contain Re: or Fwd: etc.
                $a->subject = $discussion->name;
                $threadtopic = html_to_text(get_string('postmailsubject', 'forum', $a), 0);
                $userfrom->customheaders[] = "Thread-Topic: {$threadtopic}";
                $userfrom->customheaders[] = "Thread-Index: " . substr($rootid, 1, 28);
                // Send the post now!
                mtrace('Sending ', '');
                $eventdata = new \core\message\message();
                $eventdata->courseid = $course->id;
                $eventdata->component = 'mod_forum';
                $eventdata->name = 'posts';
                $eventdata->userfrom = $userfrom;
                $eventdata->userto = $userto;
                $eventdata->subject = $postsubject;
                $eventdata->fullmessage = $textout->render($data);
                $eventdata->fullmessageformat = FORMAT_PLAIN;
                $eventdata->fullmessagehtml = $htmlout->render($data);
                $eventdata->notification = 1;
                $eventdata->replyto = $replyaddress;
                if (!empty($replyaddress)) {
                    // Add extra text to email messages if they can reply back.
                    $textfooter = "\n\n" . get_string('replytopostbyemail', 'mod_forum');
                    $htmlfooter = html_writer::tag('p', get_string('replytopostbyemail', 'mod_forum'));
                    $additionalcontent = array('fullmessage' => array('footer' => $textfooter), 'fullmessagehtml' => array('footer' => $htmlfooter));
                    $eventdata->set_additional_content('email', $additionalcontent);
                }
                $smallmessagestrings = new stdClass();
                $smallmessagestrings->user = fullname($userfrom);
                $smallmessagestrings->forumname = "{$shortname}: " . format_string($forum->name, true) . ": " . $discussion->name;
                $smallmessagestrings->message = $post->message;
                // Make sure strings are in message recipients language.
                $eventdata->smallmessage = get_string_manager()->get_string('smallmessage', 'forum', $smallmessagestrings, $userto->lang);
                $contexturl = new moodle_url('/mod/forum/discuss.php', array('d' => $discussion->id), 'p' . $post->id);
                $eventdata->contexturl = $contexturl->out();
                $eventdata->contexturlname = $discussion->name;
                $mailresult = message_send($eventdata);
                if (!$mailresult) {
                    mtrace("Error: mod/forum/lib.php forum_cron(): Could not send out mail for id {$post->id} to user {$userto->id}" . " ({$userto->email}) .. not trying again.");
                    $errorcount[$post->id]++;
                } else {
                    $mailcount[$post->id]++;
                    // Mark post as read if forum_usermarksread is set off.
                    if (!$CFG->forum_usermarksread) {
                        $userto->markposts[$post->id] = $post->id;
                    }
                }
                mtrace('post ' . $post->id . ': ' . $post->subject);
            }
            // Mark processed posts as read.
            if (get_user_preferences('forum_markasreadonnotification', 1, $userto->id) == 1) {
                forum_tp_mark_posts_read($userto, $userto->markposts);
            }
            unset($userto);
        }
    }
    if ($posts) {
        foreach ($posts as $post) {
            mtrace($mailcount[$post->id] . " users were sent post {$post->id}, '{$post->subject}'");
            if ($errorcount[$post->id]) {
                $DB->set_field('forum_posts', 'mailed', FORUM_MAILED_ERROR, array('id' => $post->id));
            }
        }
    }
    // release some memory
    unset($subscribedusers);
    unset($mailcount);
    unset($errorcount);
    cron_setup_user();
    $sitetimezone = core_date::get_server_timezone();
    // Now see if there are any digest mails waiting to be sent, and if we should send them
    mtrace('Starting digest processing...');
    core_php_time_limit::raise(300);
    // terminate if not able to fetch all digests in 5 minutes
    if (!isset($CFG->digestmailtimelast)) {
        // To catch the first time
        set_config('digestmailtimelast', 0);
    }
    $timenow = time();
    $digesttime = usergetmidnight($timenow, $sitetimezone) + $CFG->digestmailtime * 3600;
    // Delete any really old ones (normally there shouldn't be any)
    $weekago = $timenow - 7 * 24 * 3600;
    $DB->delete_records_select('forum_queue', "timemodified < ?", array($weekago));
    mtrace('Cleaned old digest records');
    if ($CFG->digestmailtimelast < $digesttime and $timenow > $digesttime) {
        mtrace('Sending forum digests: ' . userdate($timenow, '', $sitetimezone));
        $digestposts_rs = $DB->get_recordset_select('forum_queue', "timemodified < ?", array($digesttime));
        if ($digestposts_rs->valid()) {
            // We have work to do
            $usermailcount = 0;
            //caches - reuse the those filled before too
            $discussionposts = array();
            $userdiscussions = array();
            foreach ($digestposts_rs as $digestpost) {
                if (!isset($posts[$digestpost->postid])) {
                    if ($post = $DB->get_record('forum_posts', array('id' => $digestpost->postid))) {
                        $posts[$digestpost->postid] = $post;
                    } else {
                        continue;
                    }
                }
                $discussionid = $digestpost->discussionid;
                if (!isset($discussions[$discussionid])) {
                    if ($discussion = $DB->get_record('forum_discussions', array('id' => $discussionid))) {
                        $discussions[$discussionid] = $discussion;
                    } else {
                        continue;
                    }
                }
                $forumid = $discussions[$discussionid]->forum;
                if (!isset($forums[$forumid])) {
                    if ($forum = $DB->get_record('forum', array('id' => $forumid))) {
                        $forums[$forumid] = $forum;
                    } else {
                        continue;
                    }
                }
                $courseid = $forums[$forumid]->course;
                if (!isset($courses[$courseid])) {
                    if ($course = $DB->get_record('course', array('id' => $courseid))) {
                        $courses[$courseid] = $course;
                    } else {
                        continue;
                    }
                }
                if (!isset($coursemodules[$forumid])) {
                    if ($cm = get_coursemodule_from_instance('forum', $forumid, $courseid)) {
                        $coursemodules[$forumid] = $cm;
                    } else {
                        continue;
                    }
                }
                $userdiscussions[$digestpost->userid][$digestpost->discussionid] = $digestpost->discussionid;
                $discussionposts[$digestpost->discussionid][$digestpost->postid] = $digestpost->postid;
            }
            $digestposts_rs->close();
            /// Finished iteration, let's close the resultset
            // Data collected, start sending out emails to each user
            foreach ($userdiscussions as $userid => $thesediscussions) {
                core_php_time_limit::raise(120);
                // terminate if processing of any account takes longer than 2 minutes
                cron_setup_user();
                mtrace(get_string('processingdigest', 'forum', $userid), '... ');
                // First of all delete all the queue entries for this user
                $DB->delete_records_select('forum_queue', "userid = ? AND timemodified < ?", array($userid, $digesttime));
                // Init user caches - we keep the cache for one cycle only,
                // otherwise it would unnecessarily consume memory.
                if (array_key_exists($userid, $users) and isset($users[$userid]->username)) {
                    $userto = clone $users[$userid];
                } else {
                    $userto = $DB->get_record('user', array('id' => $userid));
                    forum_cron_minimise_user_record($userto);
                }
                $userto->viewfullnames = array();
                $userto->canpost = array();
                $userto->markposts = array();
                // Override the language and timezone of the "current" user, so that
                // mail is customised for the receiver.
                cron_setup_user($userto);
                $postsubject = get_string('digestmailsubject', 'forum', format_string($site->shortname, true));
                $headerdata = new stdClass();
                $headerdata->sitename = format_string($site->fullname, true);
                $headerdata->userprefs = $CFG->wwwroot . '/user/forum.php?id=' . $userid . '&amp;course=' . $site->id;
                $posttext = get_string('digestmailheader', 'forum', $headerdata) . "\n\n";
                $headerdata->userprefs = '<a target="_blank" href="' . $headerdata->userprefs . '">' . get_string('digestmailprefs', 'forum') . '</a>';
                $posthtml = '<p>' . get_string('digestmailheader', 'forum', $headerdata) . '</p>' . '<br /><hr size="1" noshade="noshade" />';
                foreach ($thesediscussions as $discussionid) {
                    core_php_time_limit::raise(120);
                    // to be reset for each post
                    $discussion = $discussions[$discussionid];
                    $forum = $forums[$discussion->forum];
                    $course = $courses[$forum->course];
                    $cm = $coursemodules[$forum->id];
                    //override language
                    cron_setup_user($userto, $course);
                    // Fill caches
                    if (!isset($userto->viewfullnames[$forum->id])) {
                        $modcontext = context_module::instance($cm->id);
                        $userto->viewfullnames[$forum->id] = has_capability('moodle/site:viewfullnames', $modcontext);
                    }
                    if (!isset($userto->canpost[$discussion->id])) {
                        $modcontext = context_module::instance($cm->id);
                        $userto->canpost[$discussion->id] = forum_user_can_post($forum, $discussion, $userto, $cm, $course, $modcontext);
                    }
                    $strforums = get_string('forums', 'forum');
                    $canunsubscribe = !\mod_forum\subscriptions::is_forcesubscribed($forum);
                    $canreply = $userto->canpost[$discussion->id];
                    $shortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
                    $posttext .= "\n \n";
                    $posttext .= '=====================================================================';
                    $posttext .= "\n \n";
                    $posttext .= "{$shortname} -> {$strforums} -> " . format_string($forum->name, true);
                    if ($discussion->name != $forum->name) {
                        $posttext .= " -> " . format_string($discussion->name, true);
                    }
                    $posttext .= "\n";
                    $posttext .= $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $discussion->id;
                    $posttext .= "\n";
                    $posthtml .= "<p><font face=\"sans-serif\">" . "<a target=\"_blank\" href=\"{$CFG->wwwroot}/course/view.php?id={$course->id}\">{$shortname}</a> -> " . "<a target=\"_blank\" href=\"{$CFG->wwwroot}/mod/forum/index.php?id={$course->id}\">{$strforums}</a> -> " . "<a target=\"_blank\" href=\"{$CFG->wwwroot}/mod/forum/view.php?f={$forum->id}\">" . format_string($forum->name, true) . "</a>";
                    if ($discussion->name == $forum->name) {
                        $posthtml .= "</font></p>";
                    } else {
                        $posthtml .= " -> <a target=\"_blank\" href=\"{$CFG->wwwroot}/mod/forum/discuss.php?d={$discussion->id}\">" . format_string($discussion->name, true) . "</a></font></p>";
                    }
                    $posthtml .= '<p>';
                    $postsarray = $discussionposts[$discussionid];
                    sort($postsarray);
                    $sentcount = 0;
                    foreach ($postsarray as $postid) {
                        $post = $posts[$postid];
                        if (array_key_exists($post->userid, $users)) {
                            // we might know him/her already
                            $userfrom = $users[$post->userid];
                            if (!isset($userfrom->idnumber)) {
                                $userfrom = $DB->get_record('user', array('id' => $userfrom->id));
                                forum_cron_minimise_user_record($userfrom);
                            }
                        } else {
                            if ($userfrom = $DB->get_record('user', array('id' => $post->userid))) {
                                forum_cron_minimise_user_record($userfrom);
                                if ($userscount <= FORUM_CRON_USER_CACHE) {
                                    $userscount++;
                                    $users[$userfrom->id] = $userfrom;
                                }
                            } else {
                                mtrace('Could not find user ' . $post->userid);
                                continue;
                            }
                        }
                        if (!isset($userfrom->groups[$forum->id])) {
                            if (!isset($userfrom->groups)) {
                                $userfrom->groups = array();
                                if (isset($users[$userfrom->id])) {
                                    $users[$userfrom->id]->groups = array();
                                }
                            }
                            $userfrom->groups[$forum->id] = groups_get_all_groups($course->id, $userfrom->id, $cm->groupingid);
                            if (isset($users[$userfrom->id])) {
                                $users[$userfrom->id]->groups[$forum->id] = $userfrom->groups[$forum->id];
                            }
                        }
                        // Headers to help prevent auto-responders.
                        $userfrom->customheaders = array("Precedence: Bulk", 'X-Auto-Response-Suppress: All', 'Auto-Submitted: auto-generated');
                        $maildigest = forum_get_user_maildigest_bulk($digests, $userto, $forum->id);
                        if (!isset($userto->canpost[$discussion->id])) {
                            $canreply = forum_user_can_post($forum, $discussion, $userto, $cm, $course, $modcontext);
                        } else {
                            $canreply = $userto->canpost[$discussion->id];
                        }
                        $data = new \mod_forum\output\forum_post_email($course, $cm, $forum, $discussion, $post, $userfrom, $userto, $canreply);
                        if (!isset($userto->viewfullnames[$forum->id])) {
                            $data->viewfullnames = has_capability('moodle/site:viewfullnames', $modcontext, $userto->id);
                        } else {
                            $data->viewfullnames = $userto->viewfullnames[$forum->id];
                        }
                        if ($maildigest == 2) {
                            // Subjects and link only.
                            $posttext .= $textdigestbasicout->render($data);
                            $posthtml .= $htmldigestbasicout->render($data);
                        } else {
                            // The full treatment.
                            $posttext .= $textdigestfullout->render($data);
                            $posthtml .= $htmldigestfullout->render($data);
                            // Create an array of postid's for this user to mark as read.
                            if (!$CFG->forum_usermarksread) {
                                $userto->markposts[$post->id] = $post->id;
                            }
                        }
                        $sentcount++;
                    }
                    $footerlinks = array();
                    if ($canunsubscribe) {
                        $footerlinks[] = "<a href=\"{$CFG->wwwroot}/mod/forum/subscribe.php?id={$forum->id}\">" . get_string("unsubscribe", "forum") . "</a>";
                    } else {
                        $footerlinks[] = get_string("everyoneissubscribed", "forum");
                    }
                    $footerlinks[] = "<a href='{$CFG->wwwroot}/mod/forum/index.php?id={$forum->course}'>" . get_string("digestmailpost", "forum") . '</a>';
                    $posthtml .= "\n<div class='mdl-right'><font size=\"1\">" . implode('&nbsp;', $footerlinks) . '</font></div>';
                    $posthtml .= '<hr size="1" noshade="noshade" /></p>';
                }
                if (empty($userto->mailformat) || $userto->mailformat != 1) {
                    // This user DOESN'T want to receive HTML
                    $posthtml = '';
                }
                $eventdata = new \core\message\message();
                $eventdata->courseid = SITEID;
                $eventdata->component = 'mod_forum';
                $eventdata->name = 'digests';
                $eventdata->userfrom = core_user::get_noreply_user();
                $eventdata->userto = $userto;
                $eventdata->subject = $postsubject;
                $eventdata->fullmessage = $posttext;
                $eventdata->fullmessageformat = FORMAT_PLAIN;
                $eventdata->fullmessagehtml = $posthtml;
                $eventdata->notification = 1;
                $eventdata->smallmessage = get_string('smallmessagedigest', 'forum', $sentcount);
                $mailresult = message_send($eventdata);
                if (!$mailresult) {
                    mtrace("ERROR: mod/forum/cron.php: Could not send out digest mail to user {$userto->id} " . "({$userto->email})... not trying again.");
                } else {
                    mtrace("success.");
                    $usermailcount++;
                    // Mark post as read if forum_usermarksread is set off
                    if (get_user_preferences('forum_markasreadonnotification', 1, $userto->id) == 1) {
                        forum_tp_mark_posts_read($userto, $userto->markposts);
                    }
                }
            }
        }
        /// We have finishied all digest emails, update $CFG->digestmailtimelast
        set_config('digestmailtimelast', $timenow);
    }
    cron_setup_user();
    if (!empty($usermailcount)) {
        mtrace(get_string('digestsentusers', 'forum', $usermailcount));
    }
    if (!empty($CFG->forum_lastreadclean)) {
        $timenow = time();
        if ($CFG->forum_lastreadclean + 24 * 3600 < $timenow) {
            set_config('forum_lastreadclean', $timenow);
            mtrace('Removing old forum read tracking info...');
            forum_tp_clean_read_records();
        }
    } else {
        set_config('forum_lastreadclean', time());
    }
    return true;
}
Example #9
0
/**
 * This function will empty a course of user data.
 * It will retain the activities and the structure of the course.
 *
 * @param object $data an object containing all the settings including courseid (without magic quotes)
 * @return array status array of array component, item, error
 */
function reset_course_userdata($data)
{
    global $CFG, $DB;
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->libdir . '/completionlib.php';
    require_once $CFG->dirroot . '/group/lib.php';
    $data->courseid = $data->id;
    $context = context_course::instance($data->courseid);
    $eventparams = array('context' => $context, 'courseid' => $data->id, 'other' => array('reset_options' => (array) $data));
    $event = \core\event\course_reset_started::create($eventparams);
    $event->trigger();
    // Calculate the time shift of dates.
    if (!empty($data->reset_start_date)) {
        // Time part of course startdate should be zero.
        $data->timeshift = $data->reset_start_date - usergetmidnight($data->reset_start_date_old);
    } else {
        $data->timeshift = 0;
    }
    // Result array: component, item, error.
    $status = array();
    // Start the resetting.
    $componentstr = get_string('general');
    // Move the course start time.
    if (!empty($data->reset_start_date) and $data->timeshift) {
        // Change course start data.
        $DB->set_field('course', 'startdate', $data->reset_start_date, array('id' => $data->courseid));
        // Update all course and group events - do not move activity events.
        $updatesql = "UPDATE {event}\n                         SET timestart = timestart + ?\n                       WHERE courseid=? AND instance=0";
        $DB->execute($updatesql, array($data->timeshift, $data->courseid));
        // Update any date activity restrictions.
        if ($CFG->enableavailability) {
            \availability_date\condition::update_all_dates($data->courseid, $data->timeshift);
        }
        $status[] = array('component' => $componentstr, 'item' => get_string('datechanged'), 'error' => false);
    }
    if (!empty($data->reset_end_date)) {
        // If the user set a end date value respect it.
        $DB->set_field('course', 'enddate', $data->reset_end_date, array('id' => $data->courseid));
    } else {
        if ($data->timeshift > 0 && $data->reset_end_date_old) {
            // If there is a time shift apply it to the end date as well.
            $enddate = $data->reset_end_date_old + $data->timeshift;
            $DB->set_field('course', 'enddate', $enddate, array('id' => $data->courseid));
        }
    }
    if (!empty($data->reset_events)) {
        $DB->delete_records('event', array('courseid' => $data->courseid));
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteevents', 'calendar'), 'error' => false);
    }
    if (!empty($data->reset_notes)) {
        require_once $CFG->dirroot . '/notes/lib.php';
        note_delete_all($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletenotes', 'notes'), 'error' => false);
    }
    if (!empty($data->delete_blog_associations)) {
        require_once $CFG->dirroot . '/blog/lib.php';
        blog_remove_associations_for_course($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteblogassociations', 'blog'), 'error' => false);
    }
    if (!empty($data->reset_completion)) {
        // Delete course and activity completion information.
        $course = $DB->get_record('course', array('id' => $data->courseid));
        $cc = new completion_info($course);
        $cc->delete_all_completion_data();
        $status[] = array('component' => $componentstr, 'item' => get_string('deletecompletiondata', 'completion'), 'error' => false);
    }
    if (!empty($data->reset_competency_ratings)) {
        \core_competency\api::hook_course_reset_competency_ratings($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletecompetencyratings', 'core_competency'), 'error' => false);
    }
    $componentstr = get_string('roles');
    if (!empty($data->reset_roles_overrides)) {
        $children = $context->get_child_contexts();
        foreach ($children as $child) {
            $DB->delete_records('role_capabilities', array('contextid' => $child->id));
        }
        $DB->delete_records('role_capabilities', array('contextid' => $context->id));
        // Force refresh for logged in users.
        $context->mark_dirty();
        $status[] = array('component' => $componentstr, 'item' => get_string('deletecourseoverrides', 'role'), 'error' => false);
    }
    if (!empty($data->reset_roles_local)) {
        $children = $context->get_child_contexts();
        foreach ($children as $child) {
            role_unassign_all(array('contextid' => $child->id));
        }
        // Force refresh for logged in users.
        $context->mark_dirty();
        $status[] = array('component' => $componentstr, 'item' => get_string('deletelocalroles', 'role'), 'error' => false);
    }
    // First unenrol users - this cleans some of related user data too, such as forum subscriptions, tracking, etc.
    $data->unenrolled = array();
    if (!empty($data->unenrol_users)) {
        $plugins = enrol_get_plugins(true);
        $instances = enrol_get_instances($data->courseid, true);
        foreach ($instances as $key => $instance) {
            if (!isset($plugins[$instance->enrol])) {
                unset($instances[$key]);
                continue;
            }
        }
        foreach ($data->unenrol_users as $withroleid) {
            if ($withroleid) {
                $sql = "SELECT ue.*\n                          FROM {user_enrolments} ue\n                          JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n                          JOIN {context} c ON (c.contextlevel = :courselevel AND c.instanceid = e.courseid)\n                          JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.roleid = :roleid AND ra.userid = ue.userid)";
                $params = array('courseid' => $data->courseid, 'roleid' => $withroleid, 'courselevel' => CONTEXT_COURSE);
            } else {
                // Without any role assigned at course context.
                $sql = "SELECT ue.*\n                          FROM {user_enrolments} ue\n                          JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n                          JOIN {context} c ON (c.contextlevel = :courselevel AND c.instanceid = e.courseid)\n                     LEFT JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.userid = ue.userid)\n                         WHERE ra.id IS null";
                $params = array('courseid' => $data->courseid, 'courselevel' => CONTEXT_COURSE);
            }
            $rs = $DB->get_recordset_sql($sql, $params);
            foreach ($rs as $ue) {
                if (!isset($instances[$ue->enrolid])) {
                    continue;
                }
                $instance = $instances[$ue->enrolid];
                $plugin = $plugins[$instance->enrol];
                if (!$plugin->allow_unenrol($instance) and !$plugin->allow_unenrol_user($instance, $ue)) {
                    continue;
                }
                $plugin->unenrol_user($instance, $ue->userid);
                $data->unenrolled[$ue->userid] = $ue->userid;
            }
            $rs->close();
        }
    }
    if (!empty($data->unenrolled)) {
        $status[] = array('component' => $componentstr, 'item' => get_string('unenrol', 'enrol') . ' (' . count($data->unenrolled) . ')', 'error' => false);
    }
    $componentstr = get_string('groups');
    // Remove all group members.
    if (!empty($data->reset_groups_members)) {
        groups_delete_group_members($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('removegroupsmembers', 'group'), 'error' => false);
    }
    // Remove all groups.
    if (!empty($data->reset_groups_remove)) {
        groups_delete_groups($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroups', 'group'), 'error' => false);
    }
    // Remove all grouping members.
    if (!empty($data->reset_groupings_members)) {
        groups_delete_groupings_groups($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('removegroupingsmembers', 'group'), 'error' => false);
    }
    // Remove all groupings.
    if (!empty($data->reset_groupings_remove)) {
        groups_delete_groupings($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroupings', 'group'), 'error' => false);
    }
    // Look in every instance of every module for data to delete.
    $unsupportedmods = array();
    if ($allmods = $DB->get_records('modules')) {
        foreach ($allmods as $mod) {
            $modname = $mod->name;
            $modfile = $CFG->dirroot . '/mod/' . $modname . '/lib.php';
            $moddeleteuserdata = $modname . '_reset_userdata';
            // Function to delete user data.
            if (file_exists($modfile)) {
                if (!$DB->count_records($modname, array('course' => $data->courseid))) {
                    continue;
                    // Skip mods with no instances.
                }
                include_once $modfile;
                if (function_exists($moddeleteuserdata)) {
                    $modstatus = $moddeleteuserdata($data);
                    if (is_array($modstatus)) {
                        $status = array_merge($status, $modstatus);
                    } else {
                        debugging('Module ' . $modname . ' returned incorrect staus - must be an array!');
                    }
                } else {
                    $unsupportedmods[] = $mod;
                }
            } else {
                debugging('Missing lib.php in ' . $modname . ' module!');
            }
        }
    }
    // Mention unsupported mods.
    if (!empty($unsupportedmods)) {
        foreach ($unsupportedmods as $mod) {
            $status[] = array('component' => get_string('modulenameplural', $mod->name), 'item' => '', 'error' => get_string('resetnotimplemented'));
        }
    }
    $componentstr = get_string('gradebook', 'grades');
    // Reset gradebook,.
    if (!empty($data->reset_gradebook_items)) {
        remove_course_grades($data->courseid, false);
        grade_grab_course_grades($data->courseid);
        grade_regrade_final_grades($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('removeallcourseitems', 'grades'), 'error' => false);
    } else {
        if (!empty($data->reset_gradebook_grades)) {
            grade_course_reset($data->courseid);
            $status[] = array('component' => $componentstr, 'item' => get_string('removeallcoursegrades', 'grades'), 'error' => false);
        }
    }
    // Reset comments.
    if (!empty($data->reset_comments)) {
        require_once $CFG->dirroot . '/comment/lib.php';
        comment::reset_course_page_comments($context);
    }
    $event = \core\event\course_reset_ended::create($eventparams);
    $event->trigger();
    return $status;
}
Example #10
0
    /**
     * Returns today sessions suitable for copying attendance log
     *
     * Fetches data from {attendance_sessions}
     *
     * @return array of records or an empty array
     */
    public function get_today_sessions_for_copy($sess) {
        global $DB;

        $count = sizeof($sess);
        if ($count > 0) {
            $start = usergetmidnight($sess->sessdate);

            $sql = "SELECT *
                  FROM {local_attendance_sessions}
                 WHERE sessdate >= :start AND sessdate <= :end AND
                       (groupid = 0 OR groupid = :groupid) AND
                       lasttaken > 0 AND attendanceid = :aid";
            $params = array(
                'start' => $start,
                'end' => $sess->sessdate,
                'groupid' => $sess->groupid,
                'aid' => $this->id);

            return $DB->get_records_sql($sql, $params);
        } else
            return array();
    }
Example #11
0
 /**
  * Send expiry notifications.
  *
  * Plugin that wants to have expiry notification MUST implement following:
  * - expirynotifyhour plugin setting,
  * - configuration options in instance edit form (expirynotify, notifyall and expirythreshold),
  * - notification strings (expirymessageenrollersubject, expirymessageenrollerbody,
  *   expirymessageenrolledsubject and expirymessageenrolledbody),
  * - expiry_notification provider in db/messages.php,
  * - upgrade code that sets default thresholds for existing courses (should be 1 day),
  * - something that calls this method, such as cron.
  *
  * @param bool $verbose verbose CLI output
  */
 public function send_expiry_notifications($verbose = false)
 {
     global $DB, $CFG;
     // Unfortunately this may take a long time, it should not be interrupted,
     // otherwise users get duplicate notification.
     @set_time_limit(0);
     raise_memory_limit(MEMORY_HUGE);
     $name = $this->get_name();
     $expirynotifylast = $this->get_config('expirynotifylast', 0);
     $expirynotifyhour = $this->get_config('expirynotifyhour');
     if (is_null($expirynotifyhour)) {
         debugging("send_expiry_notifications() in {$name} enrolment plugin needs expirynotifyhour setting");
         return;
     }
     $timenow = time();
     $notifytime = usergetmidnight($timenow, $CFG->timezone) + $expirynotifyhour * 3600;
     if ($expirynotifylast > $notifytime) {
         if ($verbose) {
             mtrace($name . ' enrolment expiry notifications were already sent today at ' . userdate($expirynotifylast, '', $CFG->timezone) . '.');
         }
         return;
     } else {
         if ($timenow < $notifytime) {
             if ($verbose) {
                 mtrace($name . ' enrolment expiry notifications will be sent at ' . userdate($notifytime, '', $CFG->timezone) . '.');
             }
             return;
         }
     }
     if ($verbose) {
         mtrace('Processing ' . $name . ' enrolment expiration notifications...');
     }
     // Notify users responsible for enrolment once every day.
     $sql = "SELECT ue.*, e.expirynotify, e.notifyall, e.expirythreshold, e.courseid, c.fullname\n                  FROM {user_enrolments} ue\n                  JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = :name AND e.expirynotify > 0 AND e.status = :enabled)\n                  JOIN {course} c ON (c.id = e.courseid)\n                  JOIN {user} u ON (u.id = ue.userid AND u.deleted = 0 AND u.suspended = 0)\n                 WHERE ue.status = :active AND ue.timeend > 0 AND ue.timeend > :now1 AND ue.timeend < (e.expirythreshold + :now2)\n              ORDER BY ue.enrolid ASC, u.lastname ASC, u.firstname ASC, u.id ASC";
     $params = array('enabled' => ENROL_INSTANCE_ENABLED, 'active' => ENROL_USER_ACTIVE, 'now1' => $timenow, 'now2' => $timenow, 'name' => $name);
     $rs = $DB->get_recordset_sql($sql, $params);
     $lastenrollid = 0;
     $users = array();
     foreach ($rs as $ue) {
         if ($lastenrollid and $lastenrollid != $ue->enrolid) {
             $this->notify_expiry_enroller($lastenrollid, $users, $verbose);
             $users = array();
         }
         $lastenrollid = $ue->enrolid;
         $enroller = $this->get_enroller($ue->enrolid);
         $context = context_course::instance($ue->courseid);
         $user = $DB->get_record('user', array('id' => $ue->userid));
         $users[] = array('fullname' => fullname($user, has_capability('moodle/site:viewfullnames', $context, $enroller)), 'timeend' => $ue->timeend);
         if (!$ue->notifyall) {
             continue;
         }
         if ($ue->timeend - $ue->expirythreshold + 86400 < $timenow) {
             // Notify enrolled users only once at the start of the threshold.
             if ($verbose) {
                 mtrace("  user {$ue->userid} was already notified that enrolment in course {$ue->courseid} expires on " . userdate($ue->timeend, '', $CFG->timezone));
             }
             continue;
         }
         $this->notify_expiry_enrolled($user, $ue, $verbose);
     }
     $rs->close();
     if ($lastenrollid and $users) {
         $this->notify_expiry_enroller($lastenrollid, $users, $verbose);
     }
     if ($verbose) {
         mtrace('...notification processing finished.');
     }
     $this->set_config('expirynotifylast', $timenow);
 }
Example #12
0
function construct_sessions_data_for_add($formdata)
{
    global $CFG;
    $duration = $formdata->durtime['hours'] * HOURSECS + $formdata->durtime['minutes'] * MINSECS;
    $now = time();
    $sessions = array();
    if (isset($formdata->addmultiply)) {
        $startdate = $formdata->sessiondate;
        $starttime = $startdate - usergetmidnight($startdate);
        $enddate = $formdata->sessionenddate + DAYSECS;
        // because enddate in 0:0am
        if ($enddate < $startdate) {
            return NULL;
        }
        $days = (int) ceil(($enddate - $startdate) / DAYSECS);
        // Getting first day of week
        $sdate = $startdate;
        $dinfo = usergetdate($sdate);
        if ($CFG->calendar_startwday === '0') {
            //week start from sunday
            $startweek = $startdate - $dinfo['wday'] * DAYSECS;
            //call new variable
        } else {
            $wday = $dinfo['wday'] === 0 ? 7 : $dinfo['wday'];
            $startweek = $startdate - ($wday - 1) * DAYSECS;
        }
        $wdaydesc = array(0 => 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
        while ($sdate < $enddate) {
            if ($sdate < $startweek + WEEKSECS) {
                $dinfo = usergetdate($sdate);
                if (key_exists($wdaydesc[$dinfo['wday']], $formdata->sdays)) {
                    $sess->sessdate = usergetmidnight($sdate) + $starttime;
                    $sess->duration = $duration;
                    $sess->descriptionitemid = $formdata->sdescription['itemid'];
                    $sess->description = $formdata->sdescription['text'];
                    $sess->descriptionformat = $formdata->sdescription['format'];
                    $sess->timemodified = $now;
                    fill_groupid($formdata, $sessions, $sess);
                }
                $sdate += DAYSECS;
            } else {
                $startweek += WEEKSECS * $formdata->period;
                $sdate = $startweek;
            }
        }
    } else {
        $sess->sessdate = $formdata->sessiondate;
        $sess->duration = $duration;
        $sess->descriptionitemid = $formdata->sdescription['itemid'];
        $sess->description = $formdata->sdescription['text'];
        $sess->descriptionformat = $formdata->sdescription['format'];
        $sess->timemodified = $now;
        fill_groupid($formdata, $sessions, $sess);
    }
    return $sessions;
}
Example #13
0
/**
 * Performs the report function.
 *
 * @param array $formdata the form data
 * @param int $type the report type
 * @param string $saveto File to save the pdf report to.
 * @return bool False on failure
 * @uses $CFG, $DB
 */
function report_ncccscensus_generate_report($formdata, $type = REPORT_NCCCSCENSUS_ACTION_VIEW, $saveto = false)
{
    global $CFG, $DB;
    require_once $CFG->libdir . '/moodlelib.php';
    $reportname = 'report_ncccscensus';
    $cid = $formdata->id;
    // In case the form is hacked, set a default startdate to today at midnight.
    if (empty($formdata->startdate)) {
        $formdata->startdate = usergetmidnight(time(), get_user_timezone());
    }
    // In case the form is hacked, set a default enddate to today at midnight.
    if (empty($formdata->enddate)) {
        $formdata->enddate = $formdata->startdate;
    }
    // Advance enddate to tomorrow's midnight.
    $formdata->enddate += DAYSECS - 1;
    // This flag determines if we should display grouped users or not.
    $nogroups = isset($formdata->disablegroups) ? true : false;
    if ($nogroups) {
        $group = false;
    } else {
        // If group specified, do some validation.
        $group = isset($formdata->group) ? $formdata->group : false;
        // In case the form is hacked, the group could be invalid.
        if ($group === false || $group < 0) {
            throw new report_ncccscensus_exception('cannotfindgroup');
        }
        if ($group > 0) {
            // Validate the group ID.
            if (!groups_group_exists($group)) {
                throw new report_ncccscensus_exception('cannotfindgroup');
            }
            // Validate the group ID with respect to the course ID.
            $groupdata = groups_get_course_data($cid);
            $groupfound = false;
            foreach ($groupdata->groups as $groupobject) {
                if ($groupobject->id == $group) {
                    $groupfound = true;
                    break;
                }
            }
            if (!$groupfound) {
                throw new report_ncccscensus_exception('invalidgroupid');
            }
            // User could still hack form to view a group that they don't have the capability to see.
            $context = context_course::instance($cid);
            if (has_capability('moodle/site:accessallgroups', $context)) {
                $userid = 0;
            } else {
                if (has_capability('moodle/course:managegroups', $context)) {
                    $userid = $USER->id;
                } else {
                    $userid = false;
                }
            }
            if ($userid === false) {
                throw new report_ncccscensus_exception('invalidgroupid');
            }
            if ($userid != 0) {
                $grouprecs = groups_get_all_groups($course->id, $userid, 0, 'g.id, g.name');
                $groupnotfound = true;
                foreach ($grouprecs as $grouprec) {
                    if ($grouprec->id == $group) {
                        $groupnotfound = false;
                        break;
                    }
                }
                if ($groupnotfound) {
                    throw new report_ncccscensus_exception('invalidgroupid');
                }
            }
        }
    }
    $users = array();
    if ($nogroups) {
        $users = report_ncccscensus_get_users($cid, REPORT_NCCCSCENSUS_EXCLUDE_GROUP_MEMBERS);
    } else {
        if ($group > 0) {
            $users = report_ncccscensus_get_users($cid, $group);
        } else {
            $users = report_ncccscensus_get_users($cid);
        }
    }
    $results = report_ncccscensus_build_grades_array($cid, $users, $formdata->startdate, $formdata->enddate);
    if (empty($results)) {
        return false;
    }
    if ($type == REPORT_NCCCSCENSUS_ACTION_VIEW) {
        $headers = array('student' => get_string('studentfullnamehtml', $reportname));
        $showstudentid = report_ncccscensus_check_field_status('showstudentid', 'html');
    } else {
        if ($type == REPORT_NCCCSCENSUS_ACTION_CSV) {
            $headers = array('student' => get_string('studentfullnamecsv', $reportname));
            $showstudentid = report_ncccscensus_check_field_status('showstudentid', 'csv');
        } else {
            $headers = array('student' => get_string('studentfullnamepdf', $reportname));
            $showstudentid = report_ncccscensus_check_field_status('showstudentid', 'pdf');
        }
    }
    if ($showstudentid) {
        $headers['studentid'] = get_string('studentid', $reportname);
    }
    $headers['activity'] = get_string('activityname', $reportname);
    $headers['module'] = get_string('activitymodule', $reportname);
    $headers['status'] = get_string('submissionstatus', $reportname);
    $headers['datesubmitted'] = get_string('submissiondate', $reportname);
    $headers['grade'] = get_string('grade', $reportname);
    $headers['gradedate'] = get_string('gradedate', $reportname);
    $context = context_course::instance($cid);
    $namesarrayview = array();
    $namesarraypdf = array();
    $instructors = ' - ';
    $viewlink = ': <a href="' . $CFG->wwwroot . '/user/view.php?id=';
    if (!empty($CFG->coursecontact)) {
        $coursecontactroles = explode(',', $CFG->coursecontact);
        sort($coursecontactroles);
        // If a user has multiple roles, we do not want to show user multiple times as a contact.
        $teachers = array();
        foreach ($coursecontactroles as $roleid) {
            $roleid = (int) $roleid;
            if ($users = get_role_users($roleid, $context, true)) {
                $role = $DB->get_record('role', array('id' => $roleid));
                $rolename = format_string(role_get_name($role, $context));
                foreach ($users as $teacher) {
                    // The $teachers array tracks whether a user is already a course contact.
                    if (!isset($teachers[$teacher->id])) {
                        $teachers[$teacher->id] = true;
                        $fullname = fullname($teacher, has_capability('moodle/site:viewfullnames', $context));
                        $namesarrayview[] = $rolename . $viewlink . $teacher->id . '&amp;course=' . SITEID . '">' . $fullname . '</a>';
                        $namesarraycsv[] = $rolename . ': ' . $fullname;
                        $namesarraypdf[] = $rolename . ': ' . $fullname;
                    }
                }
            }
        }
    }
    if ($type != REPORT_NCCCSCENSUS_ACTION_PDF) {
        if ($type == REPORT_NCCCSCENSUS_ACTION_VIEW) {
            // Create legend for HTML view.
            $legend = new html_table();
            $legend->head = array(get_string('legend', $reportname));
            $legend->headspan = array(2);
            $legendrow1colour = new html_table_cell();
            $legendrow1colour->style = 'width: 50px; background-color: ' . get_config('report_ncccscensus', 'gradeoverridecolour');
            $legendrow1[] = $legendrow1colour;
            $legendrow1[] = get_string('legendgradeoverride', $reportname);
            $legendrow2colour = new html_table_cell();
            $legendrow2colour->style = 'width: 50px; background-color: ' . get_config('report_ncccscensus', 'gradenogradecolour');
            $legendrow2[] = $legendrow2colour;
            $legendrow2[] = get_string('legendnograde', $reportname);
            $legend->data = array($legendrow1, $legendrow2);
            $legendalign = array('center', 'left');
            $legend->align = $legendalign;
        }
        $table = new html_table();
        $table->head = $headers;
        $align = array('left');
        $numheaders = count($headers);
        for ($i = 1; $i < $numheaders; $i++) {
            $align[] = 'center';
        }
        $table->align = $align;
        $table->data = array();
        foreach ($results as $result) {
            $datum = array();
            $datum[] = $result->student;
            if ($showstudentid) {
                $datum[] = $result->studentid;
            }
            $datum[] = $result->activity;
            $datum[] = $result->module;
            $status = $result->status;
            $grade = $result->grade;
            if ($type == REPORT_NCCCSCENSUS_ACTION_VIEW && $grade == get_string('nograde', $reportname)) {
                $specialstatus = new html_table_cell($status);
                $specialstatus->style = 'background-color: ' . get_config('report_ncccscensus', 'gradenogradecolour');
                $status = $specialstatus;
            } else {
                if ($type == REPORT_NCCCSCENSUS_ACTION_VIEW && $result->overridden) {
                    $specialstatus = new html_table_cell($status);
                    $specialstatus->style = 'background-color: ' . get_config('report_ncccscensus', 'gradeoverridecolour');
                    $status = $specialstatus;
                }
            }
            $datum[] = $status;
            $datum[] = $result->submitdate;
            if ($type == REPORT_NCCCSCENSUS_ACTION_VIEW && $grade == get_string('nograde', $reportname)) {
                $nograde = new html_table_cell($grade);
                $nograde->style = 'background-color: ' . get_config('report_ncccscensus', 'gradenogradecolour');
                $grade = $nograde;
            } else {
                if ($type == REPORT_NCCCSCENSUS_ACTION_VIEW && $result->overridden) {
                    $overriddengrade = new html_table_cell($grade);
                    $overriddengrade->style = 'background-color: ' . get_config('report_ncccscensus', 'gradeoverridecolour');
                    $grade = $overriddengrade;
                }
            }
            $datum[] = $grade;
            $datum[] = $result->date;
            $table->data[] = $datum;
        }
    }
    $course = $DB->get_record('course', array('id' => $cid));
    if ($group > 0) {
        $groupname = groups_get_group_name($group);
    }
    $datestring = 'n/j/y';
    $reportrange = date($datestring, $formdata->startdate) . ' - ' . date($datestring, $formdata->enddate);
    if ($type != REPORT_NCCCSCENSUS_ACTION_VIEW) {
        $date = usergetdate(time(), get_user_timezone());
        $filename = 'CensusRpt2_';
        $filename .= date('MdY_Hi', mktime($date['hours'], $date['minutes'], 0, $date['mon'], $date['mday'], $date['year']));
    }
    if ($type == REPORT_NCCCSCENSUS_ACTION_VIEW) {
        if (report_ncccscensus_check_field_status('showcoursename', 'html')) {
            echo '<b>' . get_string('coursetitle', $reportname) . ':</b> ' . $course->fullname . '<br>';
        }
        if (report_ncccscensus_check_field_status('showcoursecode', 'html')) {
            echo '<b>' . get_string('coursecode', $reportname) . ':</b> ' . $course->shortname . '<br>';
        }
        // Only show course ID if present.
        if (report_ncccscensus_check_field_status('showcourseid', 'html') && $course->idnumber !== '') {
            echo '<b>' . get_string('courseid', $reportname) . ':</b> ' . $course->idnumber . '<br>';
        }
        if (report_ncccscensus_check_field_status('showteachername', 'html')) {
            if (!empty($namesarrayview)) {
                $instructors = implode(', ', $namesarrayview);
                echo '<b>' . get_string('instructor', $reportname) . ':</b> ' . $instructors . '<br>';
            }
        }
        echo '<b>' . get_string('reportrange', $reportname) . ':</b> ' . $reportrange . '<br>';
        if (isset($groupname)) {
            echo '<b>' . get_string('section', $reportname) . ':</b> ' . $groupname . '<br>';
        } else {
            echo '<b>' . get_string('section', $reportname) . ':</b> ' . get_string('allgroupspdf', $reportname) . '<br>';
        }
        echo '<br>';
        echo html_writer::table($table);
        echo '<div id="studentfootnote" style="font-size:10px;">' . get_string('studentfootnote', $reportname) . '</div>';
        echo '<br>';
        echo html_writer::table($legend);
        echo '<br><div align="center"><a href="' . $CFG->wwwroot . '/report/ncccscensus/index.php?id=' . $formdata->id . '">';
        echo get_string('backtoreport', 'report_ncccscensus') . '</a></div>';
    } else {
        if ($type == REPORT_NCCCSCENSUS_ACTION_PDF) {
            $topheaders = array();
            $topheaders['student'] = get_string('student', $reportname);
            $topheaders['activity'] = get_string('activity', $reportname);
            $topheaders['submission'] = get_string('submission', $reportname);
            $topheaders['grade'] = get_string('grade', $reportname);
            $bottomheaders = array();
            $bottomheaders['student'] = array('fullname' => get_string('studentfullnamepdf', $reportname));
            $showstudentid = report_ncccscensus_check_field_status('showstudentid', 'pdf');
            if ($showstudentid) {
                $bottomheaders['student']['id'] = get_string('studentidpdf', $reportname);
            }
            $bottomheaders['activity'] = array('name' => get_string('activityname', $reportname), 'module' => get_string('activitymodule', $reportname));
            $bottomheaders['submission'] = array('status' => get_string('submissionstatus', $reportname), 'date' => get_string('submissiondate', $reportname));
            $bottomheaders['grade'] = array('grade' => get_string('grade', $reportname), 'date' => get_string('gradedatepdf', $reportname));
            require_once 'report.class.php';
            $censusreport = new report();
            $censusreport->topheaders = $topheaders;
            $censusreport->bottomheaders = $bottomheaders;
            $censusreport->data = array();
            foreach ($results as $result) {
                $fieldarray = array();
                $fieldarray['studentfullname'] = $result->student;
                if ($showstudentid) {
                    $fieldarray['studentid'] = $result->studentid;
                }
                $fieldarray['activityname'] = $result->activity;
                $fieldarray['activitymodule'] = $result->module;
                $fieldarray['submissionstatus'] = $result->status;
                $fieldarray['submissiondate'] = $result->submitdate;
                $fieldarray['gradegrade'] = $result->grade;
                $fieldarray['gradedate'] = $result->date;
                $censusreport->data[] = array('data' => $fieldarray, 'override' => $result->overridden != 0 ? true : false, 'nograde' => $result->grade == get_string('nograde', $reportname) ? true : false);
            }
            $censusreport->filename = $filename . '.pdf';
            if (report_ncccscensus_check_field_status('showcoursename', 'pdf')) {
                $censusreport->top[] = array(get_string('coursetitlepdf', $reportname) . ':', $course->fullname);
            }
            if (report_ncccscensus_check_field_status('showcoursecode', 'pdf')) {
                $censusreport->top[] = array(get_string('coursecodepdf', $reportname) . ':', $course->shortname);
            }
            if (report_ncccscensus_check_field_status('showcourseid', 'pdf') && $course->idnumber !== '') {
                $censusreport->top[] = array(get_string('courseid', $reportname) . ':', $course->idnumber);
            }
            if (report_ncccscensus_check_field_status('showteachername', 'pdf')) {
                if (!empty($namesarrayview)) {
                    $instructors = implode(', ', $namesarrayview);
                }
                $censusreport->top[] = array(get_string('instructor', $reportname) . ':', strip_tags($instructors));
            }
            $censusreport->top[] = array(get_string('reportrangepdf', $reportname) . ':', $reportrange);
            if (isset($groupname)) {
                $censusreport->top[] = array(get_string('group', $reportname) . ':', $groupname);
            } else {
                if ($group !== false) {
                    $censusreport->top[] = array(get_string('group', $reportname) . ':', get_string('allgroupspdf', $reportname));
                }
            }
            if (report_ncccscensus_check_field_status('showsignatureline', 'pdf')) {
                $censusreport->signatureline = true;
            }
            if (report_ncccscensus_check_field_status('showdateline', 'pdf')) {
                $censusreport->dateline = true;
            }
            if ($footermessage = get_config('report_ncccscensus', 'footermessage')) {
                $censusreport->bottom .= $footermessage;
            }
            $censusreport->download($saveto);
            return true;
        } else {
            if ($type == REPORT_NCCCSCENSUS_ACTION_CSV) {
                if (!empty($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) {
                    header('Expires: 0');
                    header('Cache-Control: private, pre-check=0, post-check=0, max-age=0, must-revalidate');
                    header('Connection: Keep-Alive');
                    header('Content-Language: ' . current_language());
                    header('Keep-Alive: timeout=5, max=100');
                    header('Pragma: no-cache');
                    header('Pragma: expires');
                    header('Expires: Mon, 20 Aug 1969 09:23:00 GMT');
                    header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
                }
                header('Content-Transfer-Encoding: ascii');
                header('Content-Disposition: attachment; filename=' . $filename . '.csv');
                header('Content-Type: text/comma-separated-values');
                $output = fopen('php://output', 'w');
                fputcsv($output, array(get_string('ncccscensusreport_title', 'report_ncccscensus')));
                fputcsv($output, array());
                if (report_ncccscensus_check_field_status('showcoursename', 'csv')) {
                    fputcsv($output, array(get_string('coursetitle', $reportname), $course->fullname));
                }
                if (report_ncccscensus_check_field_status('showcoursecode', 'csv')) {
                    fputcsv($output, array(get_string('coursecode', $reportname), $course->shortname));
                }
                if (report_ncccscensus_check_field_status('showcourseid', 'csv') && $course->idnumber !== '') {
                    fputcsv($output, array(get_string('courseid', $reportname), $course->idnumber));
                }
                if (!empty($namesarrayview) && report_ncccscensus_check_field_status('showteachername', 'csv')) {
                    fputcsv($output, array_merge(array(get_string('instructor', $reportname)), $namesarraycsv));
                }
                fputcsv($output, array(get_string('reportrange', $reportname), $reportrange));
                if (isset($groupname)) {
                    fputcsv($output, array(get_string('section', $reportname), $groupname));
                } else {
                    fputcsv($output, array(get_string('section', $reportname), get_string('allgroups', $reportname)));
                }
                fputcsv($output, array());
                fputcsv($output, $table->head);
                foreach ($table->data as $row) {
                    fputcsv($output, $row);
                }
                $showsignatureline = report_ncccscensus_check_field_status('showsignatureline', 'csv');
                $showdateline = report_ncccscensus_check_field_status('showdateline', 'csv');
                if ($showsignatureline || $showdateline) {
                    fputcsv($output, array());
                    if ($showsignatureline) {
                        fputcsv($output, array(get_string('certified', $reportname)));
                        fputcsv($output, array(get_string('signature', $reportname) . get_string('underscores', $reportname)));
                    }
                    if ($showdateline) {
                        fputcsv($output, array(get_string('date') . get_string('underscores', 'report_ncccscensus')));
                    }
                }
                fclose($output);
            }
        }
    }
}
Example #14
0
// If a day, month and year were passed then convert it to a timestamp. If these were passed
// then we can assume the day, month and year are passed as Gregorian, as no where in core
// should we be passing these values rather than the time. This is done for BC.
if (!empty($day) && !empty($mon) && !empty($year)) {
    if (checkdate($mon, $day, $year)) {
        $time = make_timestamp($year, $mon, $day);
    }
}
if (empty($time)) {
    $time = time();
}
if ($courseid != SITEID) {
    $url->param('course', $courseid);
}
if ($view !== 'upcoming') {
    $time = usergetmidnight($time);
    $url->param('view', $view);
}
$url->param('time', $time);
$PAGE->set_url($url);
if ($courseid != SITEID && !empty($courseid)) {
    $course = $DB->get_record('course', array('id' => $courseid));
    $courses = array($course->id => $course);
    $issite = false;
    navigation_node::override_active_url(new moodle_url('/course/view.php', array('id' => $course->id)));
} else {
    $course = get_site();
    $courses = calendar_get_default_courses();
    $issite = true;
}
require_course_login($course);
Example #15
0
if ($courseid == SITEID) {
    $PAGE->set_heading(fullname($user));
} else {
    $PAGE->set_heading($course->fullname);
}
// Trigger a user logs viewed event.
$event = \report_log\event\user_report_viewed::create(array('context' => $coursecontext, 'relateduserid' => $userid, 'other' => array('mode' => $mode)));
$event->trigger();
echo $OUTPUT->header();
if ($courseid != SITEID) {
    $userheading = array('user' => $user, 'usercontext' => $personalcontext);
    echo $OUTPUT->context_header($userheading, 2);
}
// Time to filter records from.
if ($mode === 'today') {
    $timefrom = usergetmidnight(time());
} else {
    $timefrom = 0;
}
$output = $PAGE->get_renderer('report_log');
$reportlog = new report_log_renderable($logreader, $course, $user->id, 0, '', -1, -1, false, false, true, false, $PAGE->url, $timefrom, '', $page, $perpage, 'timecreated DESC');
// Setup table if log reader is enabled.
if (!empty($reportlog->selectedlogreader)) {
    $reportlog->setup_table();
    $reportlog->tablelog->is_downloadable(false);
}
echo $output->reader_selector($reportlog);
if ($mode === 'all') {
    $reportlog->selecteddate = 0;
}
// Print the graphic chart accordingly to the mode (all, today).
Example #16
0
File: lib.php Project: ruddj/moodle
/**
 * Function to be run periodically according to the moodle cron
 * This function searches for things that need to be done, such
 * as sending out mail, toggling flags etc ...
 *
 * @global stdClass
 * @global object
 * @return boolean
 */
function scorm_cron () {
    global $CFG, $DB;

    require_once($CFG->dirroot.'/mod/scorm/locallib.php');

    $sitetimezone = $CFG->timezone;
    // Now see if there are any scorm updates to be done.

    if (!isset($CFG->scorm_updatetimelast)) {    // To catch the first time.
        set_config('scorm_updatetimelast', 0);
    }

    $timenow = time();
    $updatetime = usergetmidnight($timenow, $sitetimezone);

    if ($CFG->scorm_updatetimelast < $updatetime and $timenow > $updatetime) {

        set_config('scorm_updatetimelast', $timenow);

        mtrace('Updating scorm packages which require daily update');// We are updating.

        $scormsupdate = $DB->get_records('scorm', array('updatefreq' => SCORM_UPDATE_EVERYDAY));
        foreach ($scormsupdate as $scormupdate) {
            scorm_parse($scormupdate, true);
        }

        // Now clear out AICC session table with old session data.
        $cfgscorm = get_config('scorm');
        if (!empty($cfgscorm->allowaicchacp)) {
            $expiretime = time() - ($cfgscorm->aicchacpkeepsessiondata * 24 * 60 * 60);
            $DB->delete_records_select('scorm_aicc_session', 'timemodified < ?', array($expiretime));
        }
    }

    return true;
}
Example #17
0
/**
* Function to be run periodically according to the moodle cron
* This function searches for things that need to be done, such
* as sending out mail, toggling flags etc ...
*
* @return boolean
*/
function scorm_cron()
{
    global $CFG;
    require_once 'locallib.php';
    $sitetimezone = $CFG->timezone;
    /// Now see if there are any digest mails waiting to be sent, and if we should send them
    if (!isset($CFG->scorm_updatetimelast)) {
        // To catch the first time
        set_config('scorm_updatetimelast', 0);
    }
    $timenow = time();
    $updatetime = usergetmidnight($timenow, $sitetimezone) + $CFG->scorm_updatetime * 3600;
    if ($CFG->scorm_updatetimelast < $updatetime and $timenow > $updatetime) {
        set_config('scorm_updatetimelast', $timenow);
        mtrace('Updating scorm packages which require daily update');
        //We are updating
        $scormsupdate = get_records('scorm', 'updatefreq', UPDATE_EVERYDAY);
        if (!empty($scormsupdate)) {
            foreach ($scormsupdate as $scormupdate) {
                $scormupdate->instance = $scormupdate->id;
                $id = scorm_update_instance($scormupdate);
            }
        }
    }
    return true;
}
Example #18
0
/**
 * This function will empty a course of user data.
 * It will retain the activities and the structure of the course.
 *
 * @param object $data an object containing all the settings including courseid (without magic quotes)
 * @return array status array of array component, item, error
 */
function reset_course_userdata($data)
{
    global $CFG, $USER, $DB;
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->libdir . '/completionlib.php';
    require_once $CFG->dirroot . '/group/lib.php';
    $data->courseid = $data->id;
    $context = get_context_instance(CONTEXT_COURSE, $data->courseid);
    // calculate the time shift of dates
    if (!empty($data->reset_start_date)) {
        // time part of course startdate should be zero
        $data->timeshift = $data->reset_start_date - usergetmidnight($data->reset_start_date_old);
    } else {
        $data->timeshift = 0;
    }
    // result array: component, item, error
    $status = array();
    // start the resetting
    $componentstr = get_string('general');
    // move the course start time
    if (!empty($data->reset_start_date) and $data->timeshift) {
        // change course start data
        $DB->set_field('course', 'startdate', $data->reset_start_date, array('id' => $data->courseid));
        // update all course and group events - do not move activity events
        $updatesql = "UPDATE {event}\n                         SET timestart = timestart + ?\n                       WHERE courseid=? AND instance=0";
        $DB->execute($updatesql, array($data->timeshift, $data->courseid));
        $status[] = array('component' => $componentstr, 'item' => get_string('datechanged'), 'error' => false);
    }
    if (!empty($data->reset_logs)) {
        $DB->delete_records('log', array('course' => $data->courseid));
        $status[] = array('component' => $componentstr, 'item' => get_string('deletelogs'), 'error' => false);
    }
    if (!empty($data->reset_events)) {
        $DB->delete_records('event', array('courseid' => $data->courseid));
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteevents', 'calendar'), 'error' => false);
    }
    if (!empty($data->reset_notes)) {
        require_once $CFG->dirroot . '/notes/lib.php';
        note_delete_all($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletenotes', 'notes'), 'error' => false);
    }
    if (!empty($data->delete_blog_associations)) {
        require_once $CFG->dirroot . '/blog/lib.php';
        blog_remove_associations_for_course($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteblogassociations', 'blog'), 'error' => false);
    }
    if (!empty($data->reset_course_completion)) {
        // Delete course completion information
        $course = $DB->get_record('course', array('id' => $data->courseid));
        $cc = new completion_info($course);
        $cc->delete_course_completion_data();
        $status[] = array('component' => $componentstr, 'item' => get_string('deletecoursecompletiondata', 'completion'), 'error' => false);
    }
    $componentstr = get_string('roles');
    if (!empty($data->reset_roles_overrides)) {
        $children = get_child_contexts($context);
        foreach ($children as $child) {
            $DB->delete_records('role_capabilities', array('contextid' => $child->id));
        }
        $DB->delete_records('role_capabilities', array('contextid' => $context->id));
        //force refresh for logged in users
        mark_context_dirty($context->path);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletecourseoverrides', 'role'), 'error' => false);
    }
    if (!empty($data->reset_roles_local)) {
        $children = get_child_contexts($context);
        foreach ($children as $child) {
            role_unassign_all(array('contextid' => $child->id));
        }
        //force refresh for logged in users
        mark_context_dirty($context->path);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletelocalroles', 'role'), 'error' => false);
    }
    // First unenrol users - this cleans some of related user data too, such as forum subscriptions, tracking, etc.
    $data->unenrolled = array();
    if (!empty($data->unenrol_users)) {
        $plugins = enrol_get_plugins(true);
        $instances = enrol_get_instances($data->courseid, true);
        foreach ($instances as $key => $instance) {
            if (!isset($plugins[$instance->enrol])) {
                unset($instances[$key]);
                continue;
            }
            if (!$plugins[$instance->enrol]->allow_unenrol($instance)) {
                unset($instances[$key]);
            }
        }
        $sqlempty = $DB->sql_empty();
        foreach ($data->unenrol_users as $withroleid) {
            $sql = "SELECT DISTINCT ue.userid, ue.enrolid\n                      FROM {user_enrolments} ue\n                      JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n                      JOIN {context} c ON (c.contextlevel = :courselevel AND c.instanceid = e.courseid)\n                      JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.roleid = :roleid AND ra.userid = ue.userid)";
            $params = array('courseid' => $data->courseid, 'roleid' => $withroleid, 'courselevel' => CONTEXT_COURSE);
            $rs = $DB->get_recordset_sql($sql, $params);
            foreach ($rs as $ue) {
                if (!isset($instances[$ue->enrolid])) {
                    continue;
                }
                $plugins[$instances[$ue->enrolid]->enrol]->unenrol_user($instances[$ue->enrolid], $ue->userid);
                $data->unenrolled[$ue->userid] = $ue->userid;
            }
        }
    }
    if (!empty($data->unenrolled)) {
        $status[] = array('component' => $componentstr, 'item' => get_string('unenrol', 'enrol') . ' (' . count($data->unenrolled) . ')', 'error' => false);
    }
    $componentstr = get_string('groups');
    // remove all group members
    if (!empty($data->reset_groups_members)) {
        groups_delete_group_members($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('removegroupsmembers', 'group'), 'error' => false);
    }
    // remove all groups
    if (!empty($data->reset_groups_remove)) {
        groups_delete_groups($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroups', 'group'), 'error' => false);
    }
    // remove all grouping members
    if (!empty($data->reset_groupings_members)) {
        groups_delete_groupings_groups($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('removegroupingsmembers', 'group'), 'error' => false);
    }
    // remove all groupings
    if (!empty($data->reset_groupings_remove)) {
        groups_delete_groupings($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroupings', 'group'), 'error' => false);
    }
    // Look in every instance of every module for data to delete
    $unsupported_mods = array();
    if ($allmods = $DB->get_records('modules')) {
        foreach ($allmods as $mod) {
            $modname = $mod->name;
            if (!$DB->count_records($modname, array('course' => $data->courseid))) {
                continue;
                // skip mods with no instances
            }
            $modfile = $CFG->dirroot . '/mod/' . $modname . '/lib.php';
            $moddeleteuserdata = $modname . '_reset_userdata';
            // Function to delete user data
            if (file_exists($modfile)) {
                include_once $modfile;
                if (function_exists($moddeleteuserdata)) {
                    $modstatus = $moddeleteuserdata($data);
                    if (is_array($modstatus)) {
                        $status = array_merge($status, $modstatus);
                    } else {
                        debugging('Module ' . $modname . ' returned incorrect staus - must be an array!');
                    }
                } else {
                    $unsupported_mods[] = $mod;
                }
            } else {
                debugging('Missing lib.php in ' . $modname . ' module!');
            }
        }
    }
    // mention unsupported mods
    if (!empty($unsupported_mods)) {
        foreach ($unsupported_mods as $mod) {
            $status[] = array('component' => get_string('modulenameplural', $mod->name), 'item' => '', 'error' => get_string('resetnotimplemented'));
        }
    }
    $componentstr = get_string('gradebook', 'grades');
    // reset gradebook
    if (!empty($data->reset_gradebook_items)) {
        remove_course_grades($data->courseid, false);
        grade_grab_course_grades($data->courseid);
        grade_regrade_final_grades($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('removeallcourseitems', 'grades'), 'error' => false);
    } else {
        if (!empty($data->reset_gradebook_grades)) {
            grade_course_reset($data->courseid);
            $status[] = array('component' => $componentstr, 'item' => get_string('removeallcoursegrades', 'grades'), 'error' => false);
        }
    }
    // reset comments
    if (!empty($data->reset_comments)) {
        require_once $CFG->dirroot . '/comment/lib.php';
        comment::reset_course_page_comments($context);
    }
    return $status;
}
Example #19
0
/**
 * Get event format time
 *
 * @param calendar_event $event event object
 * @param int $now current time in gmt
 * @param array $linkparams list of params for event link
 * @param bool $usecommonwords the words as formatted date/time.
 * @param int $showtime determine the show time GMT timestamp
 * @return string $eventtime link/string for event time
 */
function calendar_format_event_time($event, $now, $linkparams = null, $usecommonwords = true, $showtime = 0)
{
    $starttime = $event->timestart;
    $endtime = $event->timestart + $event->timeduration;
    if (empty($linkparams) || !is_array($linkparams)) {
        $linkparams = array();
    }
    $linkparams['view'] = 'day';
    // OK, now to get a meaningful display...
    // Check if there is a duration for this event.
    if ($event->timeduration) {
        // Get the midnight of the day the event will start.
        $usermidnightstart = usergetmidnight($starttime);
        // Get the midnight of the day the event will end.
        $usermidnightend = usergetmidnight($endtime);
        // Check if we will still be on the same day.
        if ($usermidnightstart == $usermidnightend) {
            // Check if we are running all day.
            if ($event->timeduration == DAYSECS) {
                $time = get_string('allday', 'calendar');
            } else {
                // Specify the time we will be running this from.
                $datestart = calendar_time_representation($starttime);
                $dateend = calendar_time_representation($endtime);
                $time = $datestart . ' <strong>&raquo;</strong> ' . $dateend;
            }
            // Set printable representation.
            if (!$showtime) {
                $day = calendar_day_representation($event->timestart, $now, $usecommonwords);
                $url = calendar_get_link_href(new moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $endtime);
                $eventtime = html_writer::link($url, $day) . ', ' . $time;
            } else {
                $eventtime = $time;
            }
        } else {
            // It must spans two or more days.
            $daystart = calendar_day_representation($event->timestart, $now, $usecommonwords) . ', ';
            if ($showtime == $usermidnightstart) {
                $daystart = '';
            }
            $timestart = calendar_time_representation($event->timestart);
            $dayend = calendar_day_representation($event->timestart + $event->timeduration, $now, $usecommonwords) . ', ';
            if ($showtime == $usermidnightend) {
                $dayend = '';
            }
            $timeend = calendar_time_representation($event->timestart + $event->timeduration);
            // Set printable representation.
            if ($now >= $usermidnightstart && $now < $usermidnightstart + DAYSECS) {
                $url = calendar_get_link_href(new moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $endtime);
                $eventtime = $timestart . ' <strong>&raquo;</strong> ' . html_writer::link($url, $dayend) . $timeend;
            } else {
                $url = calendar_get_link_href(new moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $endtime);
                $eventtime = html_writer::link($url, $daystart) . $timestart . ' <strong>&raquo;</strong> ';
                $url = calendar_get_link_href(new moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $starttime);
                $eventtime .= html_writer::link($url, $dayend) . $timeend;
            }
        }
    } else {
        // There is no time duration.
        $time = calendar_time_representation($event->timestart);
        // Set printable representation.
        if (!$showtime) {
            $day = calendar_day_representation($event->timestart, $now, $usecommonwords);
            $url = calendar_get_link_href(new moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $starttime);
            $eventtime = html_writer::link($url, $day) . ', ' . trim($time);
        } else {
            $eventtime = $time;
        }
    }
    // Check if It has expired.
    if ($event->timestart + $event->timeduration < $now) {
        $eventtime = '<span class="dimmed_text">' . str_replace(' href=', ' class="dimmed" href=', $eventtime) . '</span>';
    }
    return $eventtime;
}
Example #20
0
 /**
  * Return user's deadlines from the calendar.
  *
  * Usually called twice, once for all deadlines from today, then any from the next 12 months up to the
  * max requested.
  *
  * Based on the calender function calendar_get_upcoming.
  *
  * @param array $courses ids of all user's courses.
  * @param int $maxevents to return
  * @param bool $todayonly true if only the next 24 hours to be returned
  * @return array
  */
 private static function get_upcoming_deadlines($courses, $maxevents, $todayonly = false)
 {
     $now = time();
     if ($todayonly === true) {
         $starttime = usergetmidnight($now);
         $daysinfuture = 1;
     } else {
         $starttime = usergetmidnight($now + DAYSECS + 3 * HOURSECS);
         // Avoid rare DST change issues.
         $daysinfuture = 365;
     }
     $endtime = $starttime + $daysinfuture * DAYSECS - 1;
     $userevents = false;
     $groupevents = false;
     $events = calendar_get_events($starttime, $endtime, $userevents, $groupevents, $courses);
     $processed = 0;
     $output = array();
     foreach ($events as $event) {
         if ($event->eventtype === 'course') {
             // Not an activity deadline.
             continue;
         }
         if (!empty($event->modulename)) {
             $modinfo = get_fast_modinfo($event->courseid);
             $mods = $modinfo->get_instances_of($event->modulename);
             if (isset($mods[$event->instance])) {
                 $cminfo = $mods[$event->instance];
                 if (!$cminfo->uservisible) {
                     continue;
                 }
             }
         }
         $output[$event->id] = $event;
         ++$processed;
         if ($processed >= $maxevents) {
             break;
         }
     }
     return $output;
 }
Example #21
0
 /**
  * Get the list of admin settings for this module and apply any defaults/advanced/locked settings.
  *
  * @param $datetimeoffsets array - If passed, this is an array of fieldnames => times that the
  *                         default date/time value should be relative to. If not passed, all
  *                         date/time fields are set relative to the users current midnight.
  * @return void
  */
 public function apply_admin_defaults($datetimeoffsets = array())
 {
     // This flag triggers the settings to be locked in apply_admin_locked_flags().
     $this->applyadminlockedflags = true;
     $settings = get_config($this->_modname);
     $mform = $this->_form;
     $usermidnight = usergetmidnight(time());
     $isupdate = !empty($this->_cm);
     foreach ($settings as $name => $value) {
         if (strpos('_', $name) !== false) {
             continue;
         }
         if ($mform->elementExists($name)) {
             $element = $mform->getElement($name);
             if (!$isupdate) {
                 if ($element->getType() == 'date_time_selector') {
                     $enabledsetting = $name . '_enabled';
                     if (empty($settings->{$enabledsetting})) {
                         $mform->setDefault($name, 0);
                     } else {
                         $relativetime = $usermidnight;
                         if (isset($datetimeoffsets[$name])) {
                             $relativetime = $datetimeoffsets[$name];
                         }
                         $mform->setDefault($name, $relativetime + $settings->{$name});
                     }
                 } else {
                     $mform->setDefault($name, $settings->{$name});
                 }
             }
             $advancedsetting = $name . '_adv';
             if (!empty($settings->{$advancedsetting})) {
                 $mform->setAdvanced($name);
             }
         }
     }
 }
Example #22
0
/**
 * This function will empty a course of user data.
 * It will retain the activities and the structure of the course.
 * @param object $data an object containing all the settings including courseid (without magic quotes)
 * @return array status array of array component, item, error
 */
function reset_course_userdata($data)
{
    global $CFG, $USER;
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->dirroot . '/group/lib.php';
    $data->courseid = $data->id;
    $context = get_context_instance(CONTEXT_COURSE, $data->courseid);
    // calculate the time shift of dates
    if (!empty($data->reset_start_date)) {
        // time part of course startdate should be zero
        $data->timeshift = $data->reset_start_date - usergetmidnight($data->reset_start_date_old);
    } else {
        $data->timeshift = 0;
    }
    // result array: component, item, error
    $status = array();
    // start the resetting
    $componentstr = get_string('general');
    // move the course start time
    if (!empty($data->reset_start_date) and $data->timeshift) {
        // change course start data
        set_field('course', 'startdate', $data->reset_start_date, 'id', $data->courseid);
        // update all course and group events - do not move activity events
        $updatesql = "UPDATE {$CFG->prefix}event\n                         SET timestart = timestart + ({$data->timeshift})\n                       WHERE courseid={$data->courseid} AND instance=0";
        execute_sql($updatesql, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('datechanged'), 'error' => false);
    }
    if (!empty($data->reset_logs)) {
        delete_records('log', 'course', $data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletelogs'), 'error' => false);
    }
    if (!empty($data->reset_events)) {
        delete_records('event', 'courseid', $data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteevents', 'calendar'), 'error' => false);
    }
    if (!empty($data->reset_notes)) {
        require_once $CFG->dirroot . '/notes/lib.php';
        note_delete_all($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletenotes', 'notes'), 'error' => false);
    }
    $componentstr = get_string('roles');
    if (!empty($data->reset_roles_overrides)) {
        $children = get_child_contexts($context);
        foreach ($children as $child) {
            delete_records('role_capabilities', 'contextid', $child->id);
        }
        delete_records('role_capabilities', 'contextid', $context->id);
        //force refresh for logged in users
        mark_context_dirty($context->path);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletecourseoverrides', 'role'), 'error' => false);
    }
    if (!empty($data->reset_roles_local)) {
        $children = get_child_contexts($context);
        foreach ($children as $child) {
            role_unassign(0, 0, 0, $child->id);
        }
        //force refresh for logged in users
        mark_context_dirty($context->path);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletelocalroles', 'role'), 'error' => false);
    }
    // First unenrol users - this cleans some of related user data too, such as forum subscriptions, tracking, etc.
    $data->unenrolled = array();
    if (!empty($data->reset_roles)) {
        foreach ($data->reset_roles as $roleid) {
            if ($users = get_role_users($roleid, $context, false, 'u.id', 'u.id ASC')) {
                foreach ($users as $user) {
                    role_unassign($roleid, $user->id, 0, $context->id);
                    if (!has_capability('moodle/course:view', $context, $user->id)) {
                        $data->unenrolled[$user->id] = $user->id;
                    }
                }
            }
        }
    }
    if (!empty($data->unenrolled)) {
        $status[] = array('component' => $componentstr, 'item' => get_string('unenrol') . ' (' . count($data->unenrolled) . ')', 'error' => false);
    }
    $componentstr = get_string('groups');
    // remove all group members
    if (!empty($data->reset_groups_members)) {
        groups_delete_group_members($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('removegroupsmembers', 'group'), 'error' => false);
    }
    // remove all groups
    if (!empty($data->reset_groups_remove)) {
        groups_delete_groups($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroups', 'group'), 'error' => false);
    }
    // remove all grouping members
    if (!empty($data->reset_groupings_members)) {
        groups_delete_groupings_groups($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('removegroupingsmembers', 'group'), 'error' => false);
    }
    // remove all groupings
    if (!empty($data->reset_groupings_remove)) {
        groups_delete_groupings($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroupings', 'group'), 'error' => false);
    }
    // Look in every instance of every module for data to delete
    $unsupported_mods = array();
    if ($allmods = get_records('modules')) {
        foreach ($allmods as $mod) {
            $modname = $mod->name;
            if (!count_records($modname, 'course', $data->courseid)) {
                continue;
                // skip mods with no instances
            }
            $modfile = $CFG->dirroot . '/mod/' . $modname . '/lib.php';
            $moddeleteuserdata = $modname . '_reset_userdata';
            // Function to delete user data
            if (file_exists($modfile)) {
                include_once $modfile;
                if (function_exists($moddeleteuserdata)) {
                    $modstatus = $moddeleteuserdata($data);
                    if (is_array($modstatus)) {
                        $status = array_merge($status, $modstatus);
                    } else {
                        debugging('Module ' . $modname . ' returned incorrect staus - must be an array!');
                    }
                } else {
                    $unsupported_mods[] = $mod;
                }
            } else {
                debugging('Missing lib.php in ' . $modname . ' module!');
            }
        }
    }
    // mention unsupported mods
    if (!empty($unsupported_mods)) {
        foreach ($unsupported_mods as $mod) {
            $status[] = array('component' => get_string('modulenameplural', $mod->name), 'item' => '', 'error' => get_string('resetnotimplemented'));
        }
    }
    $componentstr = get_string('gradebook', 'grades');
    // reset gradebook
    if (!empty($data->reset_gradebook_items)) {
        remove_course_grades($data->courseid, false);
        grade_grab_course_grades($data->courseid);
        grade_regrade_final_grades($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('removeallcourseitems', 'grades'), 'error' => false);
    } else {
        if (!empty($data->reset_gradebook_grades)) {
            grade_course_reset($data->courseid);
            $status[] = array('component' => $componentstr, 'item' => get_string('removeallcoursegrades', 'grades'), 'error' => false);
        }
    }
    return $status;
}
 /**
  * Returns today sessions suitable for copying attendance log
  *
  * Fetches data from {attendance_sessions}
  *
  * @return array of records or an empty array
  */
 public function get_today_sessions_for_copy($sess)
 {
     global $DB;
     $start = usergetmidnight($sess->sessdate);
     $sql = "SELECT *\n                  FROM {attendance_sessions}\n                 WHERE sessdate >= :start AND sessdate <= :end AND\n                       (groupid = 0 OR groupid = :groupid) AND\n                       lasttaken > 0 AND attendanceid = :aid";
     $params = array('start' => $start, 'end' => $sess->sessdate, 'groupid' => $sess->groupid, 'aid' => $this->id);
     return $DB->get_records_sql($sql, $params);
 }
Example #24
0
 function specialization()
 {
     global $CFG, $DB;
     require_once $CFG->libdir . '/filelib.php';
     $this->course = $this->page->course;
     // load userdefined title and make sure it's never empty
     if (empty($this->config->title)) {
         $this->title = get_string('pluginname', 'block_glossary_random');
     } else {
         $this->title = $this->config->title;
     }
     if (empty($this->config->glossary)) {
         return false;
     }
     if (!isset($this->config->nexttime)) {
         $this->config->nexttime = 0;
     }
     //check if it's time to put a new entry in cache
     if (time() > $this->config->nexttime) {
         // place glossary concept and definition in $pref->cache
         if (!($numberofentries = $DB->count_records('glossary_entries', array('glossaryid' => $this->config->glossary, 'approved' => 1)))) {
             $this->config->cache = get_string('noentriesyet', 'block_glossary_random');
             $this->instance_config_commit();
         }
         // Get module and context, to be able to rewrite urls
         if (!($cm = get_coursemodule_from_instance("glossary", $this->config->glossary, $this->course->id))) {
             return false;
         }
         $glossaryctx = get_context_instance(CONTEXT_MODULE, $cm->id);
         $limitfrom = 0;
         $limitnum = 1;
         switch ($this->config->type) {
             case BGR_RANDOMLY:
                 $i = rand(1, $numberofentries);
                 $limitfrom = $i - 1;
                 $SORT = 'ASC';
                 break;
             case BGR_NEXTONE:
                 if (isset($this->config->previous)) {
                     $i = $this->config->previous + 1;
                 } else {
                     $i = 1;
                 }
                 if ($i > $numberofentries) {
                     // Loop back to beginning
                     $i = 1;
                 }
                 $limitfrom = $i - 1;
                 $SORT = 'ASC';
                 break;
             default:
                 // BGR_LASTMODIFIED
                 $i = $numberofentries;
                 $limitfrom = 0;
                 $SORT = 'DESC';
                 break;
         }
         if ($entry = $DB->get_records_sql("SELECT id, concept, definition, definitionformat, definitiontrust\n                                                 FROM {glossary_entries}\n                                                WHERE glossaryid = ? AND approved = 1\n                                             ORDER BY timemodified {$SORT}", array($this->config->glossary), $limitfrom, $limitnum)) {
             $entry = reset($entry);
             if (empty($this->config->showconcept)) {
                 $text = '';
             } else {
                 $text = "<h3>" . format_string($entry->concept, true) . "</h3>";
             }
             $options = new stdClass();
             $options->trusted = $entry->definitiontrust;
             $options->overflowdiv = true;
             $entry->definition = file_rewrite_pluginfile_urls($entry->definition, 'pluginfile.php', $glossaryctx->id, 'mod_glossary', 'entry', $entry->id);
             $text .= format_text($entry->definition, $entry->definitionformat, $options);
             $this->config->nexttime = usergetmidnight(time()) + DAYSECS * $this->config->refresh;
             $this->config->previous = $i;
         } else {
             $text = get_string('noentriesyet', 'block_glossary_random');
         }
         // store the text
         $this->config->cache = $text;
         $this->instance_config_commit();
     }
 }
Example #25
0
function calendar_format_event_time($event, $now, $morehref, $usecommonwords = true, $showtime = 0)
{
    $startdate = usergetdate($event->timestart);
    $enddate = usergetdate($event->timestart + $event->timeduration);
    $usermidnightstart = usergetmidnight($event->timestart);
    if ($event->timeduration) {
        // To avoid doing the math if one IF is enough :)
        $usermidnightend = usergetmidnight($event->timestart + $event->timeduration);
    } else {
        $usermidnightend = $usermidnightstart;
    }
    // OK, now to get a meaningful display...
    // First of all we have to construct a human-readable date/time representation
    if ($event->timeduration) {
        // It has a duration
        if ($usermidnightstart == $usermidnightend || $event->timestart == $usermidnightstart && ($event->timeduration == 86400 || $event->timeduration == 86399) || $event->timestart + $event->timeduration <= $usermidnightstart + 86400) {
            // But it's all on the same day
            $timestart = calendar_time_representation($event->timestart);
            $timeend = calendar_time_representation($event->timestart + $event->timeduration);
            $time = $timestart . ' <strong>&raquo;</strong> ' . $timeend;
            if ($event->timestart == $usermidnightstart && ($event->timeduration == 86400 || $event->timeduration == 86399)) {
                $time = get_string('allday', 'calendar');
            }
            // Set printable representation
            if (!$showtime) {
                $day = calendar_day_representation($event->timestart, $now, $usecommonwords);
                $eventtime = calendar_get_link_tag($day, CALENDAR_URL . 'view.php?view=day' . $morehref . '&amp;', $enddate['mday'], $enddate['mon'], $enddate['year']) . ', ' . $time;
            } else {
                $eventtime = $time;
            }
        } else {
            // It spans two or more days
            $daystart = calendar_day_representation($event->timestart, $now, $usecommonwords) . ', ';
            if ($showtime == $usermidnightstart) {
                $daystart = '';
            }
            $timestart = calendar_time_representation($event->timestart);
            $dayend = calendar_day_representation($event->timestart + $event->timeduration, $now, $usecommonwords) . ', ';
            if ($showtime == $usermidnightend) {
                $dayend = '';
            }
            $timeend = calendar_time_representation($event->timestart + $event->timeduration);
            // Set printable representation
            if ($now >= $usermidnightstart && $now < $usermidnightstart + 86400) {
                $eventtime = $timestart . ' <strong>&raquo;</strong> ' . calendar_get_link_tag($dayend, CALENDAR_URL . 'view.php?view=day' . $morehref . '&amp;', $enddate['mday'], $enddate['mon'], $enddate['year']) . $timeend;
            } else {
                $eventtime = calendar_get_link_tag($daystart, CALENDAR_URL . 'view.php?view=day' . $morehref . '&amp;', $startdate['mday'], $startdate['mon'], $startdate['year']) . $timestart . ' <strong>&raquo;</strong> ' . calendar_get_link_tag($dayend, CALENDAR_URL . 'view.php?view=day' . $morehref . '&amp;', $enddate['mday'], $enddate['mon'], $enddate['year']) . $timeend;
            }
        }
    } else {
        $time = ' ';
        // Set printable representation
        if (!$showtime) {
            $day = calendar_day_representation($event->timestart, $now, $usecommonwords);
            $eventtime = calendar_get_link_tag($day, CALENDAR_URL . 'view.php?view=day' . $morehref . '&amp;', $startdate['mday'], $startdate['mon'], $startdate['year']) . trim($time);
        } else {
            $eventtime = $time;
        }
    }
    if ($event->timestart + $event->timeduration < $now) {
        // It has expired
        $eventtime = '<span class="dimmed_text">' . str_replace(' href=', ' class="dimmed" href=', $eventtime) . '</span>';
    }
    return $eventtime;
}
Example #26
0
/**
 * This function is used to generate and display selector form
 *
 * @global stdClass $USER
 * @global stdClass $CFG
 * @global moodle_database $DB
 * @global core_renderer $OUTPUT
 * @global stdClass $SESSION
 * @uses CONTEXT_SYSTEM
 * @uses COURSE_MAX_COURSES_PER_DROPDOWN
 * @uses CONTEXT_COURSE
 * @uses SEPARATEGROUPS
 * @param  stdClass $course course instance
 * @param  int      $selecteduser id of the selected user
 * @param  string   $selecteddate Date selected
 * @param  string   $modname course_module->id
 * @param  string   $modid number or 'site_errors'
 * @param  string   $modaction an action as recorded in the logs
 * @param  int      $selectedgroup Group to display
 * @param  int      $showcourses whether to show courses if we're over our limit.
 * @param  int      $showusers whether to show users if we're over our limit.
 * @param  string   $logformat Format of the logs (downloadascsv, showashtml, downloadasods, downloadasexcel)
 * @return void
 */
function report_plog_print_selector_form($student, $startdate = 0, $course, $metric, $test)
{
    global $USER, $CFG, $DB, $OUTPUT, $SESSION;
    $sitecontext = context_system::instance();
    $context = context_course::instance($course->id);
    if (has_capability('report/plog:viewcourse', $context)) {
        $showusers = 1;
    } else {
        $showusers = 0;
    }
    //probably remove this - not currently worried about groups (should we be though?)
    /// Setup for group handling.
    if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
        $selectedgroup = -1;
        $showgroups = false;
    } else {
        if ($course->groupmode) {
            $showgroups = true;
        } else {
            $selectedgroup = 0;
            $showgroups = false;
        }
    }
    if ($selectedgroup === -1) {
        if (isset($SESSION->currentgroup[$course->id])) {
            $selectedgroup = $SESSION->currentgroup[$course->id];
        } else {
            $selectedgroup = groups_get_all_groups($course->id, $USER->id);
            if (is_array($selectedgroup)) {
                $selectedgroup = array_shift(array_keys($selectedgroup));
                $SESSION->currentgroup[$course->id] = $selectedgroup;
            } else {
                $selectedgroup = 0;
            }
        }
    }
    // Get all the possible users
    $users = array();
    // Define limitfrom and limitnum for queries below
    // If $showusers is enabled... don't apply limitfrom and limitnum
    $limitfrom = empty($showusers) ? 0 : '';
    $limitnum = empty($showusers) ? COURSE_MAX_USERS_PER_DROPDOWN + 1 : '';
    //this needs to be modified so we don't include admin and tutors for this course in the list?
    $courseusers = get_enrolled_users($context, '', $selectedgroup, 'u.id, u.firstname, u.lastname', null, $limitfrom, $limitnum);
    if ($showusers) {
        if ($courseusers) {
            foreach ($courseusers as $courseuser) {
                $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', $context));
            }
        }
        $users[$CFG->siteguest] = get_string('guestuser');
    }
    //echo $course->id;
    //$n = "select distinct clusteringname from cluster_runs r where r.courseid = $course->id";
    $n = "select distinct clusteringname from cluster_runs r where r.courseid = {$course->id}";
    $metrica = $DB->get_records_sql($n);
    //there has to be a better way of doing this...
    $metrics = array();
    foreach ($metrica as $row) {
        $metrics[] = $row->clusteringname;
    }
    $strftimedate = get_string("strftimedate");
    $strftimedaydate = get_string("strftimedaydate");
    asort($users);
    $timenow = time();
    // GMT
    // What day is it now for the user, and when is midnight that day (in GMT).
    $timemidnight = $today = usergetmidnight($timenow);
    // Put today up the top of the list
    //$dates = array("$timemidnight" => get_string("today").", ".userdate($timenow, $strftimedate) );
    $dates = array();
    if (!$course->startdate or $course->startdate > $timenow) {
        $course->startdate = $course->timecreated;
    }
    //want to change this so we have a number of intervals
    //from start of course
    //last week
    //last fortnight
    //last month
    $numdates = 1;
    while ($timemidnight > $course->startdate and $numdates < 5) {
        $timemidnight = $timemidnight - 604800;
        //number of seconds in a week
        $timenow = $timenow - 604800;
        $dates["{$timemidnight}"] = $numdates . " weeks:" . userdate($timenow, $strftimedaydate);
        $numdates++;
    }
    echo "<form class=\"logselectform\" action=\"{$CFG->wwwroot}/report/plog/index.php\" method=\"get\">\n";
    echo "<div>\n";
    echo "<input type=\"hidden\" name=\"chooselog\" value=\"1\" />\n";
    echo "<input type=\"hidden\" name=\"showusers\" value=\"{$showusers}\" />\n";
    echo "<input type=\"hidden\" name=\"test\" value=\"{$test}\" />\n";
    if ($showusers) {
        echo html_writer::label(get_string('selctauser'), 'menuuser', false, array('class' => 'accesshide'));
        echo html_writer::select($users, "student", $student);
    }
    echo html_writer::label(get_string('date'), 'menudate', false, array('class' => 'accesshide'));
    echo html_writer::select($dates, "startdate", $startdate, get_string("alldays"));
    echo '<select id="menumetric" class="select menumetric" name="metric">';
    foreach ($metrics as $metric) {
        echo "<option value='{$metric}'>{$metric}</option>";
    }
    echo '</select>';
    //echo html_writer::select($metrics, "metric", $metric, "metric");
    echo '<input type="submit" value="' . get_string('gettheselogs') . '" />';
    echo '</div>';
    echo '</form>';
}
Example #27
0
/**
 * Function to be run periodically according to the moodle cron
 * Finds all posts that have yet to be mailed out, and mails them
 * out to all subscribers
 *
 * @global object
 * @global object
 * @global object
 * @uses CONTEXT_MODULE
 * @uses CONTEXT_COURSE
 * @uses SITEID
 * @uses FORMAT_PLAIN
 * @return void
 */
function forum_cron() {
    global $CFG, $USER, $DB;

    $site = get_site();

    // All users that are subscribed to any post that needs sending,
    // please increase $CFG->extramemorylimit on large sites that
    // send notifications to a large number of users.
    $users = array();
    $userscount = 0; // Cached user counter - count($users) in PHP is horribly slow!!!

    // status arrays
    $mailcount  = array();
    $errorcount = array();

    // caches
    $discussions     = array();
    $forums          = array();
    $courses         = array();
    $coursemodules   = array();
    $subscribedusers = array();


    // Posts older than 2 days will not be mailed.  This is to avoid the problem where
    // cron has not been running for a long time, and then suddenly people are flooded
    // with mail from the past few weeks or months
    $timenow   = time();
    $endtime   = $timenow - $CFG->maxeditingtime;
    $starttime = $endtime - 48 * 3600;   // Two days earlier

    if ($posts = forum_get_unmailed_posts($starttime, $endtime, $timenow)) {
        // Mark them all now as being mailed.  It's unlikely but possible there
        // might be an error later so that a post is NOT actually mailed out,
        // but since mail isn't crucial, we can accept this risk.  Doing it now
        // prevents the risk of duplicated mails, which is a worse problem.

        if (!forum_mark_old_posts_as_mailed($endtime)) {
            mtrace('Errors occurred while trying to mark some posts as being mailed.');
            return false;  // Don't continue trying to mail them, in case we are in a cron loop
        }

        // checking post validity, and adding users to loop through later
        foreach ($posts as $pid => $post) {

            $discussionid = $post->discussion;
            if (!isset($discussions[$discussionid])) {
                if ($discussion = $DB->get_record('forum_discussions', array('id'=> $post->discussion))) {
                    $discussions[$discussionid] = $discussion;
                } else {
                    mtrace('Could not find discussion '.$discussionid);
                    unset($posts[$pid]);
                    continue;
                }
            }
            $forumid = $discussions[$discussionid]->forum;
            if (!isset($forums[$forumid])) {
                if ($forum = $DB->get_record('forum', array('id' => $forumid))) {
                    $forums[$forumid] = $forum;
                } else {
                    mtrace('Could not find forum '.$forumid);
                    unset($posts[$pid]);
                    continue;
                }
            }
            $courseid = $forums[$forumid]->course;
            if (!isset($courses[$courseid])) {
                if ($course = $DB->get_record('course', array('id' => $courseid))) {
                    $courses[$courseid] = $course;
                } else {
                    mtrace('Could not find course '.$courseid);
                    unset($posts[$pid]);
                    continue;
                }
            }
            if (!isset($coursemodules[$forumid])) {
                if ($cm = get_coursemodule_from_instance('forum', $forumid, $courseid)) {
                    $coursemodules[$forumid] = $cm;
                } else {
                    mtrace('Could not find course module for forum '.$forumid);
                    unset($posts[$pid]);
                    continue;
                }
            }


            // caching subscribed users of each forum
            if (!isset($subscribedusers[$forumid])) {
                $modcontext = context_module::instance($coursemodules[$forumid]->id);
                if ($subusers = forum_subscribed_users($courses[$courseid], $forums[$forumid], 0, $modcontext, "u.*")) {
                    foreach ($subusers as $postuser) {
                        // this user is subscribed to this forum
                        $subscribedusers[$forumid][$postuser->id] = $postuser->id;
                        $userscount++;
                        if ($userscount > FORUM_CRON_USER_CACHE) {
                            // Store minimal user info.
                            $minuser = new stdClass();
                            $minuser->id = $postuser->id;
                            $users[$postuser->id] = $minuser;
                        } else {
                            // Cache full user record.
                            forum_cron_minimise_user_record($postuser);
                            $users[$postuser->id] = $postuser;
                        }
                    }
                    // Release memory.
                    unset($subusers);
                    unset($postuser);
                }
            }

            $mailcount[$pid] = 0;
            $errorcount[$pid] = 0;
        }
    }

    if ($users && $posts) {

        $urlinfo = parse_url($CFG->wwwroot);
        $hostname = $urlinfo['host'];

        foreach ($users as $userto) {

            @set_time_limit(120); // terminate if processing of any account takes longer than 2 minutes

            mtrace('Processing user '.$userto->id);

            // Init user caches - we keep the cache for one cycle only,
            // otherwise it could consume too much memory.
            if (isset($userto->username)) {
                $userto = clone($userto);
            } else {
                $userto = $DB->get_record('user', array('id' => $userto->id));
                forum_cron_minimise_user_record($userto);
            }
            $userto->viewfullnames = array();
            $userto->canpost       = array();
            $userto->markposts     = array();

            // set this so that the capabilities are cached, and environment matches receiving user
            cron_setup_user($userto);

            // reset the caches
            foreach ($coursemodules as $forumid=>$unused) {
                $coursemodules[$forumid]->cache       = new stdClass();
                $coursemodules[$forumid]->cache->caps = array();
                unset($coursemodules[$forumid]->uservisible);
            }

            foreach ($posts as $pid => $post) {

                // Set up the environment for the post, discussion, forum, course
                $discussion = $discussions[$post->discussion];
                $forum      = $forums[$discussion->forum];
                $course     = $courses[$forum->course];
                $cm         =& $coursemodules[$forum->id];

                // Do some checks  to see if we can bail out now
                // Only active enrolled users are in the list of subscribers
                if (!isset($subscribedusers[$forum->id][$userto->id])) {
                    continue; // user does not subscribe to this forum
                }

                // Don't send email if the forum is Q&A and the user has not posted
                // Initial topics are still mailed
                if ($forum->type == 'qanda' && !forum_get_user_posted_time($discussion->id, $userto->id) && $pid != $discussion->firstpost) {
                    mtrace('Did not email '.$userto->id.' because user has not posted in discussion');
                    continue;
                }

                // Get info about the sending user
                if (array_key_exists($post->userid, $users)) { // we might know him/her already
                    $userfrom = $users[$post->userid];
                    if (!isset($userfrom->idnumber)) {
                        // Minimalised user info, fetch full record.
                        $userfrom = $DB->get_record('user', array('id' => $userfrom->id));
                        forum_cron_minimise_user_record($userfrom);
                    }

                } else if ($userfrom = $DB->get_record('user', array('id' => $post->userid))) {
                    forum_cron_minimise_user_record($userfrom);
                    // Fetch only once if possible, we can add it to user list, it will be skipped anyway.
                    if ($userscount <= FORUM_CRON_USER_CACHE) {
                        $userscount++;
                        $users[$userfrom->id] = $userfrom;
                    }

                } else {
                    mtrace('Could not find user '.$post->userid);
                    continue;
                }

                //if we want to check that userto and userfrom are not the same person this is probably the spot to do it

                // setup global $COURSE properly - needed for roles and languages
                cron_setup_user($userto, $course);

                // Fill caches
                if (!isset($userto->viewfullnames[$forum->id])) {
                    $modcontext = context_module::instance($cm->id);
                    $userto->viewfullnames[$forum->id] = has_capability('moodle/site:viewfullnames', $modcontext);
                }
                if (!isset($userto->canpost[$discussion->id])) {
                    $modcontext = context_module::instance($cm->id);
                    $userto->canpost[$discussion->id] = forum_user_can_post($forum, $discussion, $userto, $cm, $course, $modcontext);
                }
                if (!isset($userfrom->groups[$forum->id])) {
                    if (!isset($userfrom->groups)) {
                        $userfrom->groups = array();
                        if (isset($users[$userfrom->id])) {
                            $users[$userfrom->id]->groups = array();
                        }
                    }
                    $userfrom->groups[$forum->id] = groups_get_all_groups($course->id, $userfrom->id, $cm->groupingid);
                    if (isset($users[$userfrom->id])) {
                        $users[$userfrom->id]->groups[$forum->id] = $userfrom->groups[$forum->id];
                    }
                }

                // Make sure groups allow this user to see this email
                if ($discussion->groupid > 0 and $groupmode = groups_get_activity_groupmode($cm, $course)) {   // Groups are being used
                    if (!groups_group_exists($discussion->groupid)) { // Can't find group
                        continue;                           // Be safe and don't send it to anyone
                    }

                    if (!groups_is_member($discussion->groupid) and !has_capability('moodle/site:accessallgroups', $modcontext)) {
                        // do not send posts from other groups when in SEPARATEGROUPS or VISIBLEGROUPS
                        continue;
                    }
                }

                // Make sure we're allowed to see it...
                if (!forum_user_can_see_post($forum, $discussion, $post, NULL, $cm)) {
                    mtrace('user '.$userto->id. ' can not see '.$post->id);
                    continue;
                }

                // OK so we need to send the email.

                // Does the user want this post in a digest?  If so postpone it for now.
                if ($userto->maildigest > 0) {
                    // This user wants the mails to be in digest form
                    $queue = new stdClass();
                    $queue->userid       = $userto->id;
                    $queue->discussionid = $discussion->id;
                    $queue->postid       = $post->id;
                    $queue->timemodified = $post->created;
                    $DB->insert_record('forum_queue', $queue);
                    continue;
                }


                // Prepare to actually send the post now, and build up the content

                $cleanforumname = str_replace('"', "'", strip_tags(format_string($forum->name)));

                $userfrom->customheaders = array (  // Headers to make emails easier to track
                           'Precedence: Bulk',
                           'List-Id: "'.$cleanforumname.'" <moodleforum'.$forum->id.'@'.$hostname.'>',
                           'List-Help: '.$CFG->wwwroot.'/mod/forum/view.php?f='.$forum->id,
                           'Message-ID: '.forum_get_email_message_id($post->id, $userto->id, $hostname),
                           'X-Course-Id: '.$course->id,
                           'X-Course-Name: '.format_string($course->fullname, true)
                );

                if ($post->parent) {  // This post is a reply, so add headers for threading (see MDL-22551)
                    $userfrom->customheaders[] = 'In-Reply-To: '.forum_get_email_message_id($post->parent, $userto->id, $hostname);
                    $userfrom->customheaders[] = 'References: '.forum_get_email_message_id($post->parent, $userto->id, $hostname);
                }

                $shortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));

                $postsubject = html_to_text("$shortname: ".format_string($post->subject, true));
                $posttext = forum_make_mail_text($course, $cm, $forum, $discussion, $post, $userfrom, $userto);
                $posthtml = forum_make_mail_html($course, $cm, $forum, $discussion, $post, $userfrom, $userto);

                // Send the post now!

                mtrace('Sending ', '');

                $eventdata = new stdClass();
                $eventdata->component        = 'mod_forum';
                $eventdata->name             = 'posts';
                $eventdata->userfrom         = $userfrom;
                $eventdata->userto           = $userto;
                $eventdata->subject          = $postsubject;
                $eventdata->fullmessage      = $posttext;
                $eventdata->fullmessageformat = FORMAT_PLAIN;
                $eventdata->fullmessagehtml  = $posthtml;
                $eventdata->notification = 1;

                // If forum_replytouser is not set then send mail using the noreplyaddress.
                if (empty($CFG->forum_replytouser)) {
                    // Clone userfrom as it is referenced by $users.
                    $cloneduserfrom = clone($userfrom);
                    $cloneduserfrom->email = $CFG->noreplyaddress;
                    $eventdata->userfrom = $cloneduserfrom;
                }

                $smallmessagestrings = new stdClass();
                $smallmessagestrings->user = fullname($userfrom);
                $smallmessagestrings->forumname = "$shortname: ".format_string($forum->name,true).": ".$discussion->name;
                $smallmessagestrings->message = $post->message;
                //make sure strings are in message recipients language
                $eventdata->smallmessage = get_string_manager()->get_string('smallmessage', 'forum', $smallmessagestrings, $userto->lang);

                $eventdata->contexturl = "{$CFG->wwwroot}/mod/forum/discuss.php?d={$discussion->id}#p{$post->id}";
                $eventdata->contexturlname = $discussion->name;

                $mailresult = message_send($eventdata);
                if (!$mailresult){
                    mtrace("Error: mod/forum/lib.php forum_cron(): Could not send out mail for id $post->id to user $userto->id".
                         " ($userto->email) .. not trying again.");
                    add_to_log($course->id, 'forum', 'mail error', "discuss.php?d=$discussion->id#p$post->id",
                               substr(format_string($post->subject,true),0,30), $cm->id, $userto->id);
                    $errorcount[$post->id]++;
                } else {
                    $mailcount[$post->id]++;

                // Mark post as read if forum_usermarksread is set off
                    if (!$CFG->forum_usermarksread) {
                        $userto->markposts[$post->id] = $post->id;
                    }
                }

                mtrace('post '.$post->id. ': '.$post->subject);
            }

            // mark processed posts as read
            forum_tp_mark_posts_read($userto, $userto->markposts);
            unset($userto);
        }
    }

    if ($posts) {
        foreach ($posts as $post) {
            mtrace($mailcount[$post->id]." users were sent post $post->id, '$post->subject'");
            if ($errorcount[$post->id]) {
                $DB->set_field('forum_posts', 'mailed', FORUM_MAILED_ERROR, array('id' => $post->id));
            }
        }
    }

    // release some memory
    unset($subscribedusers);
    unset($mailcount);
    unset($errorcount);

    cron_setup_user();

    $sitetimezone = $CFG->timezone;

    // Now see if there are any digest mails waiting to be sent, and if we should send them

    mtrace('Starting digest processing...');

    @set_time_limit(300); // terminate if not able to fetch all digests in 5 minutes

    if (!isset($CFG->digestmailtimelast)) {    // To catch the first time
        set_config('digestmailtimelast', 0);
    }

    $timenow = time();
    $digesttime = usergetmidnight($timenow, $sitetimezone) + ($CFG->digestmailtime * 3600);

    // Delete any really old ones (normally there shouldn't be any)
    $weekago = $timenow - (7 * 24 * 3600);
    $DB->delete_records_select('forum_queue', "timemodified < ?", array($weekago));
    mtrace ('Cleaned old digest records');

    if ($CFG->digestmailtimelast < $digesttime and $timenow > $digesttime) {

        mtrace('Sending forum digests: '.userdate($timenow, '', $sitetimezone));

        $digestposts_rs = $DB->get_recordset_select('forum_queue', "timemodified < ?", array($digesttime));

        if ($digestposts_rs->valid()) {

            // We have work to do
            $usermailcount = 0;

            //caches - reuse the those filled before too
            $discussionposts = array();
            $userdiscussions = array();

            foreach ($digestposts_rs as $digestpost) {
                if (!isset($posts[$digestpost->postid])) {
                    if ($post = $DB->get_record('forum_posts', array('id' => $digestpost->postid))) {
                        $posts[$digestpost->postid] = $post;
                    } else {
                        continue;
                    }
                }
                $discussionid = $digestpost->discussionid;
                if (!isset($discussions[$discussionid])) {
                    if ($discussion = $DB->get_record('forum_discussions', array('id' => $discussionid))) {
                        $discussions[$discussionid] = $discussion;
                    } else {
                        continue;
                    }
                }
                $forumid = $discussions[$discussionid]->forum;
                if (!isset($forums[$forumid])) {
                    if ($forum = $DB->get_record('forum', array('id' => $forumid))) {
                        $forums[$forumid] = $forum;
                    } else {
                        continue;
                    }
                }

                $courseid = $forums[$forumid]->course;
                if (!isset($courses[$courseid])) {
                    if ($course = $DB->get_record('course', array('id' => $courseid))) {
                        $courses[$courseid] = $course;
                    } else {
                        continue;
                    }
                }

                if (!isset($coursemodules[$forumid])) {
                    if ($cm = get_coursemodule_from_instance('forum', $forumid, $courseid)) {
                        $coursemodules[$forumid] = $cm;
                    } else {
                        continue;
                    }
                }
                $userdiscussions[$digestpost->userid][$digestpost->discussionid] = $digestpost->discussionid;
                $discussionposts[$digestpost->discussionid][$digestpost->postid] = $digestpost->postid;
            }
            $digestposts_rs->close(); /// Finished iteration, let's close the resultset

            // Data collected, start sending out emails to each user
            foreach ($userdiscussions as $userid => $thesediscussions) {

                @set_time_limit(120); // terminate if processing of any account takes longer than 2 minutes

                cron_setup_user();

                mtrace(get_string('processingdigest', 'forum', $userid), '... ');

                // First of all delete all the queue entries for this user
                $DB->delete_records_select('forum_queue', "userid = ? AND timemodified < ?", array($userid, $digesttime));

                // Init user caches - we keep the cache for one cycle only,
                // otherwise it would unnecessarily consume memory.
                if (array_key_exists($userid, $users) and isset($users[$userid]->username)) {
                    $userto = clone($users[$userid]);
                } else {
                    $userto = $DB->get_record('user', array('id' => $userid));
                    forum_cron_minimise_user_record($userto);
                }
                $userto->viewfullnames = array();
                $userto->canpost       = array();
                $userto->markposts     = array();

                // Override the language and timezone of the "current" user, so that
                // mail is customised for the receiver.
                cron_setup_user($userto);

                $postsubject = get_string('digestmailsubject', 'forum', format_string($site->shortname, true));

                $headerdata = new stdClass();
                $headerdata->sitename = format_string($site->fullname, true);
                $headerdata->userprefs = $CFG->wwwroot.'/user/edit.php?id='.$userid.'&amp;course='.$site->id;

                $posttext = get_string('digestmailheader', 'forum', $headerdata)."\n\n";
                $headerdata->userprefs = '<a target="_blank" href="'.$headerdata->userprefs.'">'.get_string('digestmailprefs', 'forum').'</a>';

                $posthtml = "<head>";
/*                foreach ($CFG->stylesheets as $stylesheet) {
                    //TODO: MDL-21120
                    $posthtml .= '<link rel="stylesheet" type="text/css" href="'.$stylesheet.'" />'."\n";
                }*/
                $posthtml .= "</head>\n<body id=\"email\">\n";
                $posthtml .= '<p>'.get_string('digestmailheader', 'forum', $headerdata).'</p><br /><hr size="1" noshade="noshade" />';

                foreach ($thesediscussions as $discussionid) {

                    @set_time_limit(120);   // to be reset for each post

                    $discussion = $discussions[$discussionid];
                    $forum      = $forums[$discussion->forum];
                    $course     = $courses[$forum->course];
                    $cm         = $coursemodules[$forum->id];

                    //override language
                    cron_setup_user($userto, $course);

                    // Fill caches
                    if (!isset($userto->viewfullnames[$forum->id])) {
                        $modcontext = context_module::instance($cm->id);
                        $userto->viewfullnames[$forum->id] = has_capability('moodle/site:viewfullnames', $modcontext);
                    }
                    if (!isset($userto->canpost[$discussion->id])) {
                        $modcontext = context_module::instance($cm->id);
                        $userto->canpost[$discussion->id] = forum_user_can_post($forum, $discussion, $userto, $cm, $course, $modcontext);
                    }

                    $strforums      = get_string('forums', 'forum');
                    $canunsubscribe = ! forum_is_forcesubscribed($forum);
                    $canreply       = $userto->canpost[$discussion->id];
                    $shortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));

                    $posttext .= "\n \n";
                    $posttext .= '=====================================================================';
                    $posttext .= "\n \n";
                    $posttext .= "$shortname -> $strforums -> ".format_string($forum->name,true);
                    if ($discussion->name != $forum->name) {
                        $posttext  .= " -> ".format_string($discussion->name,true);
                    }
                    $posttext .= "\n";

                    $posthtml .= "<p><font face=\"sans-serif\">".
                    "<a target=\"_blank\" href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$shortname</a> -> ".
                    "<a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/index.php?id=$course->id\">$strforums</a> -> ".
                    "<a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/view.php?f=$forum->id\">".format_string($forum->name,true)."</a>";
                    if ($discussion->name == $forum->name) {
                        $posthtml .= "</font></p>";
                    } else {
                        $posthtml .= " -> <a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$discussion->id\">".format_string($discussion->name,true)."</a></font></p>";
                    }
                    $posthtml .= '<p>';

                    $postsarray = $discussionposts[$discussionid];
                    sort($postsarray);

                    foreach ($postsarray as $postid) {
                        $post = $posts[$postid];

                        if (array_key_exists($post->userid, $users)) { // we might know him/her already
                            $userfrom = $users[$post->userid];
                            if (!isset($userfrom->idnumber)) {
                                $userfrom = $DB->get_record('user', array('id' => $userfrom->id));
                                forum_cron_minimise_user_record($userfrom);
                            }

                        } else if ($userfrom = $DB->get_record('user', array('id' => $post->userid))) {
                            forum_cron_minimise_user_record($userfrom);
                            if ($userscount <= FORUM_CRON_USER_CACHE) {
                                $userscount++;
                                $users[$userfrom->id] = $userfrom;
                            }

                        } else {
                            mtrace('Could not find user '.$post->userid);
                            continue;
                        }

                        if (!isset($userfrom->groups[$forum->id])) {
                            if (!isset($userfrom->groups)) {
                                $userfrom->groups = array();
                                if (isset($users[$userfrom->id])) {
                                    $users[$userfrom->id]->groups = array();
                                }
                            }
                            $userfrom->groups[$forum->id] = groups_get_all_groups($course->id, $userfrom->id, $cm->groupingid);
                            if (isset($users[$userfrom->id])) {
                                $users[$userfrom->id]->groups[$forum->id] = $userfrom->groups[$forum->id];
                            }
                        }

                        $userfrom->customheaders = array ("Precedence: Bulk");

                        if ($userto->maildigest == 2) {
                            // Subjects only
                            $by = new stdClass();
                            $by->name = fullname($userfrom);
                            $by->date = userdate($post->modified);
                            $posttext .= "\n".format_string($post->subject,true).' '.get_string("bynameondate", "forum", $by);
                            $posttext .= "\n---------------------------------------------------------------------";

                            $by->name = "<a target=\"_blank\" href=\"$CFG->wwwroot/user/view.php?id=$userfrom->id&amp;course=$course->id\">$by->name</a>";
                            $posthtml .= '<div><a target="_blank" href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.$discussion->id.'#p'.$post->id.'">'.format_string($post->subject,true).'</a> '.get_string("bynameondate", "forum", $by).'</div>';

                        } else {
                            // The full treatment
                            $posttext .= forum_make_mail_text($course, $cm, $forum, $discussion, $post, $userfrom, $userto, true);
                            $posthtml .= forum_make_mail_post($course, $cm, $forum, $discussion, $post, $userfrom, $userto, false, $canreply, true, false);

                        // Create an array of postid's for this user to mark as read.
                            if (!$CFG->forum_usermarksread) {
                                $userto->markposts[$post->id] = $post->id;
                            }
                        }
                    }
                    if ($canunsubscribe) {
                        $posthtml .= "\n<div class='mdl-right'><font size=\"1\"><a href=\"$CFG->wwwroot/mod/forum/subscribe.php?id=$forum->id\">".get_string("unsubscribe", "forum")."</a></font></div>";
                    } else {
                        $posthtml .= "\n<div class='mdl-right'><font size=\"1\">".get_string("everyoneissubscribed", "forum")."</font></div>";
                    }
                    $posthtml .= '<hr size="1" noshade="noshade" /></p>';
                }
                $posthtml .= '</body>';

                if (empty($userto->mailformat) || $userto->mailformat != 1) {
                    // This user DOESN'T want to receive HTML
                    $posthtml = '';
                }

                $attachment = $attachname='';
                // Directly email forum digests rather than sending them via messaging, use the
                // site shortname as 'from name', the noreply address will be used by email_to_user.
                $mailresult = email_to_user($userto, $site->shortname, $postsubject, $posttext, $posthtml, $attachment, $attachname);

                if (!$mailresult) {
                    mtrace("ERROR!");
                    echo "Error: mod/forum/cron.php: Could not send out digest mail to user $userto->id ($userto->email)... not trying again.\n";
                    add_to_log($course->id, 'forum', 'mail digest error', '', '', $cm->id, $userto->id);
                } else {
                    mtrace("success.");
                    $usermailcount++;

                    // Mark post as read if forum_usermarksread is set off
                    forum_tp_mark_posts_read($userto, $userto->markposts);
                }
            }
        }
    /// We have finishied all digest emails, update $CFG->digestmailtimelast
        set_config('digestmailtimelast', $timenow);
    }

    cron_setup_user();

    if (!empty($usermailcount)) {
        mtrace(get_string('digestsentusers', 'forum', $usermailcount));
    }

    if (!empty($CFG->forum_lastreadclean)) {
        $timenow = time();
        if ($CFG->forum_lastreadclean + (24*3600) < $timenow) {
            set_config('forum_lastreadclean', $timenow);
            mtrace('Removing old forum read tracking info...');
            forum_tp_clean_read_records();
        }
    } else {
        set_config('forum_lastreadclean', time());
    }


    return true;
}
Example #28
0
function schedule_inc_backup_next_execution($backup_course, $incremental_config, $now, $timezone)
{
    $result = -1;
    //Get today's midnight GMT
    $midnight = usergetmidnight($now, $timezone);
    //Get today's day of week (0=Sunday...6=Saturday)
    $date = usergetdate($now, $timezone);
    $dayofweek = $date['wday'];
    //Get number of days (from today) to execute backups
    $scheduled_days = substr($incremental_config->backup_inc_weekdays, $dayofweek) . $incremental_config->backup_inc_weekdays;
    $daysfromtoday = strpos($scheduled_days, "1");
    //If some day has been found
    if ($daysfromtoday !== false) {
        //Calculate distance
        $dist = $daysfromtoday * 86400 + $incremental_config->backup_inc_hour * 3600 + $incremental_config->backup_inc_minute * 60;
        //Minutes distance
        $result = $midnight + $dist;
    }
    //If that time is past, call the function recursively to obtain the next valid day
    if ($result > 0 && $result < time()) {
        $result = schedule_inc_backup_next_execution($backup_course, $incremental_config, $now + 86400, $timezone);
    }
    return $result;
}
Example #29
0
function print_log_selector_form($course, $selecteduser = 0, $selecteddate = 'today', $modname = "", $modid = 0, $modaction = '', $selectedgroup = -1, $showcourses = 0, $showusers = 0, $logformat = 'showashtml')
{
    global $USER, $CFG;
    // first check to see if we can override showcourses and showusers
    $numcourses = count_records_select("course", "", "COUNT(id)");
    if ($numcourses < COURSE_MAX_COURSES_PER_DROPDOWN && !$showcourses) {
        $showcourses = 1;
    }
    $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
    $context = get_context_instance(CONTEXT_COURSE, $course->id);
    /// Setup for group handling.
    if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
        $selectedgroup = get_current_group($course->id);
        $showgroups = false;
    } else {
        if ($course->groupmode) {
            $selectedgroup = $selectedgroup == -1 ? get_current_group($course->id) : $selectedgroup;
            $showgroups = true;
        } else {
            $selectedgroup = 0;
            $showgroups = false;
        }
    }
    // Get all the possible users
    $users = array();
    if ($course->id != SITEID) {
        if ($selectedgroup) {
            // If using a group, only get users in that group.
            $courseusers = get_group_users($selectedgroup, 'u.lastname ASC', '', 'u.id, u.firstname, u.lastname, u.idnumber');
        } else {
            $courseusers = get_course_users($course->id, '', '', 'u.id, u.firstname, u.lastname, u.idnumber');
        }
    } else {
        $courseusers = get_site_users("u.lastaccess DESC", "u.id, u.firstname, u.lastname, u.idnumber");
    }
    if (count($courseusers) < COURSE_MAX_USERS_PER_DROPDOWN && !$showusers) {
        $showusers = 1;
    }
    if ($showusers) {
        if ($courseusers) {
            foreach ($courseusers as $courseuser) {
                $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', $context));
            }
        }
        if ($guest = get_guest()) {
            $users[$guest->id] = fullname($guest);
        }
    }
    if (has_capability('moodle/site:viewreports', $sitecontext) && $showcourses) {
        if ($ccc = get_records("course", "", "", "fullname", "id,fullname,category")) {
            foreach ($ccc as $cc) {
                if ($cc->category) {
                    $courses["{$cc->id}"] = format_string($cc->fullname);
                } else {
                    $courses["{$cc->id}"] = format_string($cc->fullname) . ' (Site)';
                }
            }
        }
        asort($courses);
    }
    $activities = array();
    $selectedactivity = "";
    /// Casting $course->modinfo to string prevents one notice when the field is null
    if ($modinfo = unserialize((string) $course->modinfo)) {
        $section = 0;
        if ($course->format == 'weeks') {
            // Bodgy
            $strsection = get_string("week");
        } else {
            $strsection = get_string("topic");
        }
        foreach ($modinfo as $mod) {
            if ($mod->mod == "label") {
                continue;
            }
            if ($mod->section > 0 and $section != $mod->section) {
                $activities["section/{$mod->section}"] = "-------------- {$strsection} {$mod->section} --------------";
            }
            $section = $mod->section;
            $mod->name = strip_tags(format_string(urldecode($mod->name), true));
            if (strlen($mod->name) > 55) {
                $mod->name = substr($mod->name, 0, 50) . "...";
            }
            if (!$mod->visible) {
                $mod->name = "(" . $mod->name . ")";
            }
            $activities["{$mod->cm}"] = $mod->name;
            if ($mod->cm == $modid) {
                $selectedactivity = "{$mod->cm}";
            }
        }
    }
    if (has_capability('moodle/site:viewreports', $sitecontext) && $course->id == SITEID) {
        $activities["site_errors"] = get_string("siteerrors");
        if ($modid === "site_errors") {
            $selectedactivity = "site_errors";
        }
    }
    $strftimedate = get_string("strftimedate");
    $strftimedaydate = get_string("strftimedaydate");
    asort($users);
    // Prepare the list of action options.
    $actions = array('view' => get_string('view'), 'add' => get_string('add'), 'update' => get_string('update'), 'delete' => get_string('delete'), '-view' => get_string('allchanges'));
    // Get all the possible dates
    // Note that we are keeping track of real (GMT) time and user time
    // User time is only used in displays - all calcs and passing is GMT
    $timenow = time();
    // GMT
    // What day is it now for the user, and when is midnight that day (in GMT).
    $timemidnight = $today = usergetmidnight($timenow);
    // Put today up the top of the list
    $dates = array("{$timemidnight}" => get_string("today") . ", " . userdate($timenow, $strftimedate));
    if (!$course->startdate or $course->startdate > $timenow) {
        $course->startdate = $course->timecreated;
    }
    $numdates = 1;
    while ($timemidnight > $course->startdate and $numdates < 365) {
        $timemidnight = $timemidnight - 86400;
        $timenow = $timenow - 86400;
        $dates["{$timemidnight}"] = userdate($timenow, $strftimedaydate);
        $numdates++;
    }
    if ($selecteddate == "today") {
        $selecteddate = $today;
    }
    echo "<form class=\"logselectform\" action=\"{$CFG->wwwroot}/course/report/log/index.php\" method=\"get\">\n";
    echo "<div>\n";
    echo "<input type=\"hidden\" name=\"chooselog\" value=\"1\" />\n";
    echo "<input type=\"hidden\" name=\"showusers\" value=\"{$showusers}\" />\n";
    echo "<input type=\"hidden\" name=\"showcourses\" value=\"{$showcourses}\" />\n";
    if (has_capability('moodle/site:viewreports', $sitecontext) && $showcourses) {
        choose_from_menu($courses, "id", $course->id, "");
    } else {
        //        echo '<input type="hidden" name="id" value="'.$course->id.'" />';
        $courses = array();
        $courses[$course->id] = $course->fullname . ($course->id == SITEID ? ' (' . get_string('site') . ') ' : '');
        choose_from_menu($courses, "id", $course->id, false);
        if (has_capability('moodle/site:viewreports', $sitecontext)) {
            $a = new object();
            $a->url = "{$CFG->wwwroot}/course/report/log/index.php?chooselog=0&group={$selectedgroup}&user={$selecteduser}" . "&id={$course->id}&date={$selecteddate}&modid={$selectedactivity}&showcourses=1&showusers={$showusers}";
            print_string('logtoomanycourses', 'moodle', $a);
        }
    }
    if ($showgroups) {
        if ($cgroups = groups_get_all_groups($course->id)) {
            foreach ($cgroups as $cgroup) {
                $groups[$cgroup->id] = $cgroup->name;
            }
        } else {
            $groups = array();
        }
        choose_from_menu($groups, "group", $selectedgroup, get_string("allgroups"));
    }
    if ($showusers) {
        choose_from_menu($users, "user", $selecteduser, get_string("allparticipants"));
    } else {
        $users = array();
        if (!empty($selecteduser)) {
            $user = get_record('user', 'id', $selecteduser);
            $users[$selecteduser] = fullname($user);
        } else {
            $users[0] = get_string('allparticipants');
        }
        choose_from_menu($users, 'user', $selecteduser, false);
        $a = new object();
        $a->url = "{$CFG->wwwroot}/course/report/log/index.php?chooselog=0&group={$selectedgroup}&user={$selecteduser}" . "&id={$course->id}&date={$selecteddate}&modid={$selectedactivity}&showusers=1&showcourses={$showcourses}";
        print_string('logtoomanyusers', 'moodle', $a);
    }
    choose_from_menu($dates, "date", $selecteddate, get_string("alldays"));
    choose_from_menu($activities, "modid", $selectedactivity, get_string("allactivities"), "", "");
    choose_from_menu($actions, 'modaction', $modaction, get_string("allactions"));
    $logformats = array('showashtml' => get_string('displayonpage'), 'downloadascsv' => get_string('downloadtext'), 'downloadasods' => get_string('downloadods'), 'downloadasexcel' => get_string('downloadexcel'));
    choose_from_menu($logformats, 'logformat', $logformat, false);
    echo '<input type="submit" value="' . get_string('gettheselogs') . '" />';
    echo '</div>';
    echo '</form>';
}
 /**
  * Works out the next time the automated backup should be run.
  *
  * @param mixed $timezone
  * @param int $now
  * @return int
  */
 public static function calculate_next_automated_backup($timezone, $now)
 {
     $result = -1;
     $config = get_config('backup');
     $midnight = usergetmidnight($now, $timezone);
     $date = usergetdate($now, $timezone);
     //Get number of days (from today) to execute backups
     $automateddays = substr($config->backup_auto_weekdays, $date['wday']) . $config->backup_auto_weekdays;
     $daysfromtoday = strpos($automateddays, "1");
     if (empty($daysfromtoday)) {
         $daysfromtoday = 1;
     }
     //If some day has been found
     if ($daysfromtoday !== false) {
         //Calculate distance
         $dist = $daysfromtoday * 86400 + $config->backup_auto_hour * 3600 + $config->backup_auto_minute * 60;
         //Minutes distance
         $result = $midnight + $dist;
     }
     //If that time is past, call the function recursively to obtain the next valid day
     if ($result > 0 && $result < time()) {
         $result = self::calculate_next_automated_backup($timezone, $result);
     }
     return $result;
 }