protected function readquestions($lines)
 {
     // For this class the method has been simplified as
     // there can never be more than one question for a
     // multianswer import
     $questions = array();
     $questiontext = array();
     $questiontext['text'] = implode('', $lines);
     $questiontext['format'] = 0;
     $questiontext['itemid'] = '';
     $question = qtype_multianswer_extract_question($questiontext);
     $question->questiontext = $question->questiontext['text'];
     $question->questiontextformat = 0;
     $question->qtype = MULTIANSWER;
     $question->generalfeedback = '';
     $question->course = $this->course;
     if (!empty($question)) {
         $name = html_to_text(implode(' ', $lines));
         $name = preg_replace('/{[^}]*}/', '', $name);
         $name = trim($name);
         if ($name) {
             $question->name = shorten_text($name, 45);
         } else {
             // We need some name, so use the current time, since that will be
             // reasonably unique.
             $question->name = userdate(time());
         }
         $questions[] = $question;
     }
     return $questions;
 }
 function direct($to_email, $subject = '', $body_html = '')
 {
     $body_text = html_to_text($body_html);
     $this->CI->load->library('composer/lib_aws');
     $ses_client = $this->CI->lib_aws->get_ses();
     try {
         $result = $ses_client->sendEmail(['Destination' => ['ToAddresses' => [$to_email]], 'Message' => ['Body' => ['Html' => ['Data' => $body_html], 'Text' => ['Data' => $body_text]], 'Subject' => ['Data' => $subject]], 'Source' => '"' . app_name() . '" <' . getenv('email_postmaster') . '>']);
     } catch (AwsException $e) {
         // handle the error.
         $error_msg = 'getAwsRequestId: ' . $e->getAwsRequestId() . ', getAwsErrorType:' . $e->getAwsErrorType() . ', getAwsErrorCode:' . $e->getAwsErrorCode() . "\n\n";
         $error_msg .= $e->getMessage() . "\n";
         $error_msg .= $e->getTraceAsString();
     }
     if (empty($result)) {
         $this->error = ['message' => $error_msg];
         return NULL;
     } else {
         if (!empty($result['MessageId'])) {
             $result = $result->toArray();
             return $result;
         } else {
             $this->error = ['message' => 'Result missing MessageId', 'result' => $result];
             return NULL;
         }
     }
 }
Example #3
0
/**
 * Runs and exports, through email, the report instance specified by the
 * provided report schedule
 *
 * @param   stdClass  $report_schedule  The PHP report schedule containing the information
 *                                      about the specific report to be exported
 *
 * @return  boolean                     true on success, otherwise false
 */
function php_report_schedule_export_instance($report_schedule, $now = 0) {
    global $CFG, $USER;

    if ($now == 0) {
        $now = time();
    }

    $data = unserialize($report_schedule->config);

    // Create report to be emailed to recipient
    $shortname = $report_schedule->report;
    $format = $data['format'];
    // Initialize a temp path name
    $tmppath = '/temp';
    // Create a unique temporary filename to use for this schedule
    $filename = tempnam($CFG->dataroot.$tmppath, 'php_report_');

    $parameterdata = $data['parameters'];

    // Generate the report file
    $result = php_report::export_default_instance($shortname, $format, $filename, $parameterdata, $report_schedule->userid, php_report::EXECUTION_MODE_SCHEDULED);

    if (!$result) {
        //handle failure case
        unlink($filename);
        return false;
    }

    // Attach filename to an email - so get recipient...
    $recipients_array = explode(',',$data['recipients']);
    $from = get_string('noreplyname');
    $subject = get_string('email_subject','local_elisreports').$data['label'];
    $messagetext = html_to_text($data['message']);
    $messagehtml = $data['message'];
    $start = strlen($CFG->dataroot);
    $attachment = substr($filename,$start);
    $attachname = $report_schedule->report.$now.'.'.$data['format'];

    // $user->id & all other fields now required by Moodle 2.6+ email_to_user() API which also calls fullname($user)
    $user = new stdClass;
    $allfields = get_all_user_name_fields();
    foreach ($allfields as $field) {
        $user->$field = null;
    }
    $user->id = $USER->id; // let's just use this user as default (TBD)
    $user->mailformat = 1;

    // Attach the file to the recipients
    foreach ($recipients_array as $recipient) {
        $user->email = trim($recipient);
        email_to_user($user, $from, $subject, $messagetext, $messagehtml, $attachment, $attachname);
    }

    // Remove the file that was created for this report
    unlink($filename);

    return true;
}
 public function summarise_response(array $response)
 {
     if (isset($response['answer'])) {
         $formatoptions = new stdClass();
         $formatoptions->para = false;
         return html_to_text(format_text($response['answer'], FORMAT_HTML, $formatoptions), 0, false);
     } else {
         return null;
     }
 }
/**
 * This plugin sends users a welcome message after logging in
 * and notify a moderator a new user has been added
 * it has a settings page that allow you to configure the messages
 * send.
 *
 * @package    local
 * @subpackage welcome
 * @copyright  2014 Bas Brands, basbrands.nl, bas@sonsbeekmedia.nl
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
function send_welcome($user)
{
    global $CFG, $SITE;
    $moderator = get_admin();
    $sender = get_admin();
    if (!empty($user->email)) {
        $config = get_config('local_welcome');
        if (!empty($config->auth_plugins)) {
            $auths = explode(',', $config->auth_plugins);
            if (!in_array($user->auth, $auths)) {
                return '';
            }
        } else {
            return '';
        }
        $moderator->email = $config->moderator_email;
        $sender->email = $config->sender_email;
        $sender->firstname = $config->sender_firstname;
        $sender->lastname = $config->sender_lastname;
        $message_user_enabled = $config->message_user_enabled;
        $message_user = $config->message_user;
        $message_user_subject = $config->message_user_subject;
        $message_moderator_enabled = $config->message_moderator_enabled;
        $message_moderator = $config->message_moderator;
        $message_moderator_subject = $config->message_moderator_subject;
        if (!empty($user->country)) {
            $user->country = get_string($user->country, 'countries');
        } else {
            $user->country = '';
        }
        $sitelink = html_writer::link(new moodle_url('/'), $SITE->fullname);
        $resetpasswordlink = html_writer::link(new moodle_url('/login/forgot_password.php'), get_string('resetpass', 'local_welcome'));
        $fields = array('[[fullname]]', '[[username]]', '[[firstname]]', '[[lastname]]', '[[email]]', '[[city]]', '[[country]]', '[[sitelink]]', '[[sitename]]', '[[resetpasswordlink]]');
        $values = array(fullname($user), $user->username, $user->firstname, $user->lastname, $user->email, $user->city, $user->country, $sitelink, $SITE->fullname, $resetpasswordlink);
        $message_user = str_replace($fields, $values, $message_user);
        $message_user_subject = str_replace($fields, $values, $message_user_subject);
        $message_moderator = str_replace($fields, $values, $message_moderator);
        $message_moderator_subject = str_replace($fields, $values, $message_moderator_subject);
        if (!empty($message_user) && !empty($sender->email) && $message_user_enabled) {
            email_to_user($user, $sender, $message_user_subject, html_to_text($message_user), $message_user);
        }
        if (!empty($message_moderator) && !empty($sender->email) && $message_moderator_enabled) {
            email_to_user($moderator, $sender, $message_moderator_subject, html_to_text($message_moderator), $message_moderator);
        }
    }
}
/**
 * Runs and exports, through email, the report instance specified by the
 * provided report schedule
 *
 * @param   stdClass  $report_schedule  The PHP report schedule containing the information
 *                                      about the specific report to be exported
 *
 * @return  boolean                     true on success, otherwise false
 */
function php_report_schedule_export_instance($report_schedule, $now = 0)
{
    global $CFG;
    if ($now == 0) {
        $now = gmmktime();
        // time();
    }
    $data = unserialize($report_schedule->config);
    // Create report to be emailed to recipient
    $shortname = $report_schedule->report;
    $format = $data['format'];
    // Initialize a temp path name
    $tmppath = '/temp';
    // Create a unique temporary filename to use for this schedule
    $filename = tempnam($CFG->dataroot . $tmppath, 'php_report_');
    $parameterdata = $data['parameters'];
    // Generate the report file
    $result = php_report::export_default_instance($shortname, $format, $filename, $parameterdata, $report_schedule->userid, php_report::EXECUTION_MODE_SCHEDULED);
    if (!$result) {
        //handle failure case
        unlink($filename);
        return false;
    }
    // Attach filename to an email - so get recipient...
    $recipients_array = explode(',', $data['recipients']);
    $from = get_string('noreplyname');
    $subject = get_string('email_subject', 'block_php_report') . $data['label'];
    $messagetext = html_to_text($data['message']);
    $messagehtml = $data['message'];
    $start = strlen($CFG->dataroot);
    $attachment = substr($filename, $start);
    $attachname = $report_schedule->report . $now . '.' . $data['format'];
    // Attach the file to the recipients
    foreach ($recipients_array as $recipient) {
        $user = new stdClass();
        $user->email = $recipient;
        $user->mailformat = 1;
        email_to_user($user, $from, $subject, $messagetext, $messagehtml, $attachment, $attachname);
    }
    // Remove the file that was created for this report
    unlink($filename);
    return true;
}
Example #7
0
    public function readquestions($lines) {
        question_bank::get_qtype('multianswer'); // Ensure the multianswer code is loaded.

        // For this class the method has been simplified as
        // there can never be more than one question for a
        // multianswer import.
        $questions = array();

        $questiontext = array();
        $questiontext['text'] = implode('', $lines);
        $questiontext['format'] = FORMAT_MOODLE;
        $questiontext['itemid'] = '';
        $question = qtype_multianswer_extract_question($questiontext);
        $question->questiontext = $question->questiontext['text'];
        $question->questiontextformat = 0;

        $question->qtype = 'multianswer';
        $question->generalfeedback = '';
        $question->generalfeedbackformat = FORMAT_MOODLE;
        $question->length = 1;
        $question->penalty = 0.3333333;

        if (!empty($question)) {
            $name = html_to_text(implode(' ', $lines));
            $name = preg_replace('/{[^}]*}/', '', $name);
            $name = trim($name);

            if ($name) {
                $question->name = shorten_text($name, 45);
            } else {
                // We need some name, so use the current time, since that will be
                // reasonably unique.
                $question->name = userdate(time());
            }

            $questions[] = $question;
        }

        return $questions;
    }
Example #8
0
 /**
  *
  */
 protected function replacements(array $patterns, $entry, array $options = null)
 {
     $field = $this->_field;
     $fieldname = $field->name;
     $edit = !empty($options['edit']);
     $haseditreplacement = false;
     $editablepatterns = array("[[{$fieldname}]]", "[[{$fieldname}:text]]", "[[{$fieldname}:textlinks]]");
     $replacements = array_fill_keys(array_keys($patterns), '');
     foreach ($patterns as $pattern => $cleanpattern) {
         if ($edit and !$haseditreplacement) {
             $patterneditable = in_array($cleanpattern, $editablepatterns);
             if ($patterneditable and !($noedit = $this->is_noedit($pattern))) {
                 $required = $this->is_required($pattern);
                 $editparams = array($entry, array('required' => $required));
                 $replacements[$pattern] = array(array($this, 'display_edit'), $editparams);
                 $haseditreplacement = true;
                 continue;
             }
         }
         switch ($cleanpattern) {
             case "[[{$fieldname}]]":
                 $replacements[$pattern] = $this->display_browse($entry);
                 break;
                 // Plain text, no links.
             // Plain text, no links.
             case "[[{$fieldname}:text]]":
                 $replacements[$pattern] = html_to_text($this->display_browse($entry, array('text' => true)));
                 break;
                 // Plain text, with links.
             // Plain text, with links.
             case "[[{$fieldname}:textlinks]]":
                 $replacements[$pattern] = $this->display_browse($entry, array('text' => true, 'links' => true));
                 break;
             case "[[{$fieldname}:wordcount]]":
                 $replacements[$pattern] = $this->word_count($entry);
                 break;
         }
     }
     return $replacements;
 }
function atom_add_items($items)
{
    global $CFG;
    $result = '';
    $xhtmlattr = array('type' => 'xhtml');
    if (!empty($items)) {
        foreach ($items as $item) {
            $result .= atom_start_tag('entry', 1, true);
            $result .= atom_full_tag('title', 2, false, htmlspecialchars(html_to_text($item->title)));
            $result .= atom_full_tag('link', 2, false, null, array('href' => $item->link, 'rel' => 'alternate'));
            $result .= atom_full_tag('updated', 2, false, date_format_rfc3339($item->pubdate));
            //Include the author if exists
            if (isset($item->author)) {
                $result .= atom_start_tag('author', 2, true);
                $result .= atom_full_tag('name', 3, false, $item->author);
                $result .= atom_end_tag('author', 2, true);
            }
            $result .= atom_full_tag('content', 2, false, '<div xmlns="http://www.w3.org/1999/xhtml">' . clean_text($item->description, FORMAT_HTML) . '</div>', $xhtmlattr);
            $result .= atom_full_tag('id', 2, false, $item->link);
            if (isset($item->tags)) {
                $tagdata = array();
                if (isset($item->tagscheme)) {
                    $tagdata['scheme'] = $item->tagscheme;
                }
                foreach ($item->tags as $tag) {
                    $tagdata['term'] = $tag;
                    $result .= atom_full_tag('category', 2, true, false, $tagdata);
                }
            }
            $result .= atom_end_tag('entry', 1, true);
        }
    } else {
        $result = false;
    }
    return $result;
}
Example #10
0
    /**
     * @return string a summary of a manual comment action.
     * @param unknown_type $step
     */
    protected function summarise_manual_comment($step) {
        $a = new stdClass();
        if ($step->has_behaviour_var('comment')) {
            $a->comment = shorten_text(html_to_text($this->format_comment(
                    $step->get_behaviour_var('comment')), 0, false), 200);
        } else {
            $a->comment = '';
        }

        $mark = $step->get_behaviour_var('mark');
        if (is_null($mark) || $mark === '') {
            return get_string('commented', 'question', $a->comment);
        } else {
            $a->mark = $mark / $step->get_behaviour_var('maxmark') * $this->qa->get_max_mark();
            return get_string('manuallygraded', 'question', $a);
        }
    }
Example #11
0
/**
 * Send a message from one user to another. Will be delivered according to the message recipients messaging preferences
 *
 * @param object $userfrom the message sender
 * @param object $userto the message recipient
 * @param string $message the message
 * @param int $format message format such as FORMAT_PLAIN or FORMAT_HTML
 * @return int|false the ID of the new message or false
 */
function message_post_message($userfrom, $userto, $message, $format) {
    global $SITE, $CFG, $USER;

    $eventdata = new stdClass();
    $eventdata->component        = 'moodle';
    $eventdata->name             = 'instantmessage';
    $eventdata->userfrom         = $userfrom;
    $eventdata->userto           = $userto;

    //using string manager directly so that strings in the message will be in the message recipients language rather than the senders
    $eventdata->subject          = get_string_manager()->get_string('unreadnewmessage', 'message', fullname($userfrom), $userto->lang);

    if ($format == FORMAT_HTML) {
        $eventdata->fullmessagehtml  = $message;
        //some message processors may revert to sending plain text even if html is supplied
        //so we keep both plain and html versions if we're intending to send html
        $eventdata->fullmessage = html_to_text($eventdata->fullmessagehtml);
    } else {
        $eventdata->fullmessage      = $message;
        $eventdata->fullmessagehtml  = '';
    }

    $eventdata->fullmessageformat = $format;
    $eventdata->smallmessage     = $message;//store the message unfiltered. Clean up on output.

    $s = new stdClass();
    $s->sitename = format_string($SITE->shortname, true, array('context' => context_course::instance(SITEID)));
    $s->url = $CFG->wwwroot.'/message/index.php?user='******'&id='.$userfrom->id;

    $emailtagline = get_string_manager()->get_string('emailtagline', 'message', $s, $userto->lang);
    if (!empty($eventdata->fullmessage)) {
        $eventdata->fullmessage .= "\n\n---------------------------------------------------------------------\n".$emailtagline;
    }
    if (!empty($eventdata->fullmessagehtml)) {
        $eventdata->fullmessagehtml .= "<br /><br />---------------------------------------------------------------------<br />".$emailtagline;
    }

    $eventdata->timecreated     = time();
    $eventdata->notification    = 0;
    return message_send($eventdata);
}
Example #12
0
/**
 * Given text in a variety of format codings, this function returns the text as plain text suitable for plain email.
 *
 * @param string $text The text to be formatted. This is raw text originally from user input.
 * @param int $format Identifier of the text format to be used
 *            [FORMAT_MOODLE, FORMAT_HTML, FORMAT_PLAIN, FORMAT_WIKI, FORMAT_MARKDOWN]
 * @return string
 */
function format_text_email($text, $format)
{
    switch ($format) {
        case FORMAT_PLAIN:
            return $text;
            break;
        case FORMAT_WIKI:
            // There should not be any of these any more!
            $text = wikify_links($text);
            return core_text::entities_to_utf8(strip_tags($text), true);
            break;
        case FORMAT_HTML:
            return html_to_text($text);
            break;
        case FORMAT_MOODLE:
        case FORMAT_MARKDOWN:
        default:
            $text = wikify_links($text);
            return core_text::entities_to_utf8(strip_tags($text), true);
            break;
    }
}
Example #13
0
 /**
  * Returns the name of column in export
  * @param object $grade_item
  * @param boolean $feedback feedback colum
  * @param string $gradedisplayname grade display name.
  * @return string
  */
 public function format_column_name($grade_item, $feedback = false, $gradedisplayname = null)
 {
     $column = new stdClass();
     if ($grade_item->itemtype == 'mod') {
         $column->name = get_string('modulename', $grade_item->itemmodule) . get_string('labelsep', 'langconfig') . $grade_item->get_name();
     } else {
         $column->name = $grade_item->get_name();
     }
     // We can't have feedback and display type at the same time.
     $column->extra = $feedback ? get_string('feedback') : get_string($gradedisplayname, 'grades');
     return html_to_text(get_string('gradeexportcolumntype', 'grades', $column), 0, false);
 }
/**
 * Returns array of critical errors in plain text format
 * @param array $environment_results array of results gathered
 * @return array errors
 */
function environment_get_errors($environment_results)
{
    global $CFG;
    $errors = array();
    // Iterate over each environment_result
    foreach ($environment_results as $environment_result) {
        $type = $environment_result->getPart();
        $info = $environment_result->getInfo();
        $status = $environment_result->getStatus();
        $error_code = $environment_result->getErrorCode();
        $a = new stdClass();
        if ($error_code) {
            $a->error_code = $error_code;
            $errors[] = array($info, get_string('environmentxmlerror', 'admin', $a));
            return $errors;
        }
        /// Calculate the status value
        if ($environment_result->getBypassStr() != '') {
            // not interesting
            continue;
        } else {
            if ($environment_result->getRestrictStr() != '') {
                // error
            } else {
                if ($status) {
                    // ok
                    continue;
                } else {
                    if ($environment_result->getLevel() == 'optional') {
                        // just a warning
                        continue;
                    } else {
                        // error
                    }
                }
            }
        }
        // We are comparing versions
        $rec = new stdClass();
        if ($rec->needed = $environment_result->getNeededVersion()) {
            $rec->current = $environment_result->getCurrentVersion();
            if ($environment_result->getLevel() == 'required') {
                $stringtouse = 'environmentrequireversion';
            } else {
                $stringtouse = 'environmentrecommendversion';
            }
            // We are checking installed & enabled things
        } else {
            if ($environment_result->getPart() == 'custom_check') {
                if ($environment_result->getLevel() == 'required') {
                    $stringtouse = 'environmentrequirecustomcheck';
                } else {
                    $stringtouse = 'environmentrecommendcustomcheck';
                }
            } else {
                if ($environment_result->getPart() == 'php_setting') {
                    if ($status) {
                        $stringtouse = 'environmentsettingok';
                    } else {
                        if ($environment_result->getLevel() == 'required') {
                            $stringtouse = 'environmentmustfixsetting';
                        } else {
                            $stringtouse = 'environmentshouldfixsetting';
                        }
                    }
                } else {
                    if ($environment_result->getLevel() == 'required') {
                        $stringtouse = 'environmentrequireinstall';
                    } else {
                        $stringtouse = 'environmentrecommendinstall';
                    }
                }
            }
        }
        $report = get_string($stringtouse, 'admin', $rec);
        // Here we'll store all the feedback found
        $feedbacktext = '';
        // Append  the feedback if there is some
        $feedbacktext .= $environment_result->strToReport($environment_result->getFeedbackStr(), 'error');
        // Append the restrict if there is some
        $feedbacktext .= $environment_result->strToReport($environment_result->getRestrictStr(), 'error');
        $report .= html_to_text($feedbacktext);
        if ($environment_result->getPart() == 'custom_check') {
            $errors[] = array($info, $report);
        } else {
            $errors[] = array($info !== '' ? "{$type} {$info}" : $type, $report);
        }
    }
    return $errors;
}
 protected function bootstrap_process_message($message)
 {
     global $DB;
     $messagecontent = new stdClass();
     if ($message->notification) {
         $messagecontent->text = get_string('unreadnewnotification', 'message');
     } else {
         if ($message->fullmessageformat == FORMAT_HTML) {
             $message->smallmessage = html_to_text($message->smallmessage);
         }
         if (core_text::strlen($message->smallmessage) > 15) {
             $messagecontent->text = core_text::substr($message->smallmessage, 0, 15) . '...';
         } else {
             $messagecontent->text = $message->smallmessage;
         }
     }
     if (time() - $message->timecreated <= 3600 * 3) {
         $messagecontent->date = format_time(time() - $message->timecreated);
     } else {
         $messagecontent->date = userdate($message->timecreated, get_string('strftimetime', 'langconfig'));
     }
     $messagecontent->from = $DB->get_record('user', array('id' => $message->useridfrom));
     return $messagecontent;
 }
function update_authoriser($form, $data, $authoriser_id)
{
    // Update the stored authorisation requests
    read_form_auths($data->id, $auth);
    if ($authoriser_id == 0) {
        delete_form_auths($auth);
    } else {
        $auth->authoriser = $authoriser_id;
        $auth->request_date = time();
        write_form_auths($auth);
    }
    // Determine the URL to use to link to the form
    $program = new moodle_url('/local/obu_forms/process.php') . '?id=' . $data->id;
    // Email the new status to the author and to Student Central (if not the next authoriser)
    $author = get_complete_user_data('id', $data->author);
    $sc = get_complete_user_data('username', 'csa');
    $sc_id = $sc->id;
    if (!$form->modular) {
        // Use the default CSA Team contact and notification details (PG)
        $sc_contact = $sc;
        $sc_notifications = $sc;
    } else {
        // Use the SCAT contact and notification details (UMP)
        $sc_contact = get_complete_user_data('username', 'scat');
        $sc_notifications = get_complete_user_data('username', 'scat_notifications');
    }
    // Add email headers to help prevent auto-responders
    $author->customheaders = array('Precedence: Bulk', 'X-Auto-Response-Suppress: All', 'Auto-Submitted: auto-generated');
    $sc_contact->customheaders = array('Precedence: Bulk', 'X-Auto-Response-Suppress: All', 'Auto-Submitted: auto-generated');
    get_form_status($author->id, $form, $data, $text, $button_text);
    // get the status from the author's perspective
    // If a staff form, extract any given student number
    $student_number = '';
    if (!$form->student) {
        load_form_fields($data, $fields);
        if (array_key_exists('student_number', $fields)) {
            $student_number = ' [' . $fields['student_number'] . ']';
        }
    }
    $html = '<h4><a href="' . $program . '">' . $form->formref . ': ' . $form->name . $student_number . '</a></h4>' . $text;
    email_to_user($author, $sc_contact, 'The Status of Your Form ' . $form->formref . $student_number, html_to_text($html), $html);
    if ($authoriser_id != $sc_id) {
        get_form_status($sc_id, $form, $data, $text, $button_text);
        // get the status from the perspective of Student Central
        $html = '<h4><a href="' . $program . '">' . $form->formref . ': ' . $form->name . $student_number . '</a></h4>' . $text;
        email_to_user($sc_notifications, $author, 'Form ' . $form->formref . $student_number . ' Status Update (' . $author->username . ')', html_to_text($html), $html);
    }
    // Notify the next authoriser (if there is one)
    if ($authoriser_id) {
        if ($authoriser_id == $sc_id) {
            $authoriser = $sc_notifications;
        } else {
            $authoriser = get_complete_user_data('id', $authoriser_id);
        }
        if ($authoriser->username != 'csa-tbd') {
            // No notification possible if authoriser TBD
            $form_link = '<a href="' . $program . '">' . $form->formref . ' ' . get_string('form_title', 'local_obu_forms') . $student_number . '</a>';
            $email_link = '<a href="mailto:' . $sc_contact->email . '?Subject=' . get_string('auths', 'local_obu_forms') . '" target="_top">' . $sc_contact->email . '</a>';
            $html = get_string('request_authorisation', 'local_obu_forms', array('form' => $form_link, 'name' => $sc_contact->alternatename, 'phone' => $sc_contact->phone1, 'email' => $email_link));
            email_to_user($authoriser, $author, 'Request for Form ' . $form->formref . $student_number . ' Authorisation (' . $author->username . ')', html_to_text($html), $html);
        }
    }
}
 /**
  * Add comment
  *
  * Through this controller only logged users can post (no anonymous comments here)
  *
  * @param void
  * @return null
  */
 function add()
 {
     $this->setTemplate('add_comment');
     $object_id = get_id('object_id');
     $object = Objects::findObject($object_id);
     if (!$object instanceof ContentDataObject) {
         flash_error(lang('no access permissions'));
         ajx_current("empty");
         return;
     }
     // if
     $comment = new Comment();
     $comment_data = array_var($_POST, 'comment');
     tpl_assign('comment_form_object', $object);
     tpl_assign('comment', $comment);
     tpl_assign('comment_data', $comment_data);
     if (is_array($comment_data)) {
         try {
             try {
                 $attached_files = ProjectFiles::handleHelperUploads(active_context());
             } catch (Exception $e) {
                 $attached_files = null;
             }
             // try
             $comment->setFromAttributes($comment_data);
             $comment->setRelObjectId($object_id);
             $comment->setObjectName(substr_utf($comment->getText(), 0, 250));
             DB::beginWork();
             $comment->save();
             $comment->addToMembers($object->getMembers());
             if (is_array($attached_files)) {
                 foreach ($attached_files as $attached_file) {
                     $comment->attachFile($attached_file);
                 }
                 // foreach
             }
             // if
             // Subscribe user to object
             if (!$object->isSubscriber(logged_user())) {
                 $object->subscribeUser(logged_user());
             }
             // if
             if (strlen($comment->getText()) < 100) {
                 $comment_head = $comment->getText();
             } else {
                 $lastpos = strpos($comment->getText(), " ", 100);
                 if ($lastpos === false) {
                     $comment_head = $comment->getText();
                 } else {
                     $comment_head = substr($comment->getText(), 0, $lastpos) . "...";
                 }
             }
             $comment_head = html_to_text($comment_head);
             ApplicationLogs::createLog($comment, ApplicationLogs::ACTION_COMMENT, false, false, true, $comment_head);
             DB::commit();
             flash_success(lang('success add comment'));
             ajx_current("reload");
         } catch (Exception $e) {
             DB::rollback();
             ajx_current("empty");
             flash_error($e->getMessage());
         }
         // try
     }
     // if
 }
Example #18
0
 /**
  * Convert the question text to plain text, so it can safely be displayed
  * during import to let the user see roughly what is going on.
  */
 protected function format_question_text($question) {
     global $DB;
     $formatoptions = new stdClass();
     $formatoptions->noclean = true;
     return html_to_text(format_text($question->questiontext,
             $question->questiontextformat, $formatoptions), 0, false);
 }
Example #19
0
     } else {
         if ($end_of_task) {
             $tip_title = lang('end of task');
             $img_url = image_url('/16x16/task_end.png');
             $tip_pre = 'end_';
         } else {
             $tip_title = lang('start of task');
             $img_url = image_url('/16x16/task_start.png');
             $tip_pre = 'st_';
         }
     }
     $tip_pre .= gen_id() . "_";
     $div_prefix = 'd_ta_div_' . $tip_pre;
     $subject = $event->getObjectName();
     $divtype = '<span class="italic">' . $tip_title . '</span> - ';
     $tipBody = lang('assigned to') . ': ' . clean($event->getAssignedToName()) . (trim(clean($event->getText())) != '' ? '<br><br>' . html_to_text($event->getText()) : '');
 } elseif ($event instanceof ProjectEvent) {
     $div_prefix = 'd_ev_div_';
     $subject = clean($event->getObjectName());
     $img_url = image_url('/16x16/calendar.png');
     $divtype = '<span class="italic">' . lang('event') . '</span> - ';
     $tipBody = trim(clean($event->getDescription())) != '' ? '<br>' . clean($event->getDescription()) : '';
 } elseif ($event instanceof Contact) {
     $div_prefix = 'd_bd_div_';
     $objType = 'contact';
     $subject = clean($event->getObjectName());
     $img_url = image_url('/16x16/contacts.png');
     $divtype = '<span class="italic">' . lang('birthday') . '</span> - ';
 }
 $tipBody = str_replace("\r", '', $tipBody);
 $tipBody = str_replace("\n", '<br>', $tipBody);
Example #20
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 #21
0
 /**
  * Send welcome email to specified user.
  *
  * @param stdClass $instance
  * @param stdClass $user user record
  * @return void
  */
 protected function email_welcome_message($instance, $user)
 {
     global $CFG, $DB;
     $course = $DB->get_record('course', array('id' => $instance->courseid), '*', MUST_EXIST);
     $context = context_course::instance($course->id);
     $a = new stdClass();
     $a->coursename = format_string($course->fullname, true, array('context' => $context));
     $a->profileurl = "{$CFG->wwwroot}/user/view.php?id={$user->id}&course={$course->id}";
     if (trim($instance->customtext1) !== '') {
         $message = $instance->customtext1;
         $key = array('{$a->coursename}', '{$a->profileurl}', '{$a->fullname}', '{$a->email}');
         $value = array($a->coursename, $a->profileurl, fullname($user), $user->email);
         $message = str_replace($key, $value, $message);
         if (strpos($message, '<') === false) {
             // Plain text only.
             $messagetext = $message;
             $messagehtml = text_to_html($messagetext, null, false, true);
         } else {
             // This is most probably the tag/newline soup known as FORMAT_MOODLE.
             $messagehtml = format_text($message, FORMAT_MOODLE, array('context' => $context, 'para' => false, 'newlines' => true, 'filter' => true));
             $messagetext = html_to_text($messagehtml);
         }
     } else {
         $messagetext = get_string('welcometocoursetext', 'enrol_self', $a);
         $messagehtml = text_to_html($messagetext, null, false, true);
     }
     $subject = get_string('welcometocourse', 'enrol_self', format_string($course->fullname, true, array('context' => $context)));
     $rusers = array();
     if (!empty($CFG->coursecontact)) {
         $croles = explode(',', $CFG->coursecontact);
         list($sort, $sortparams) = users_order_by_sql('u');
         // We only use the first user.
         $i = 0;
         do {
             $rusers = get_role_users($croles[$i], $context, true, '', 'r.sortorder ASC, ' . $sort, null, '', '', '', '', $sortparams);
             $i++;
         } while (empty($rusers) && !empty($croles[$i]));
     }
     if ($rusers) {
         $contact = reset($rusers);
     } else {
         $contact = core_user::get_support_user();
     }
     // Directly emailing welcome message rather than using messaging.
     email_to_user($user, $contact, $subject, $messagetext, $messagehtml);
 }
Example #22
0
 /**
  * Given a grade_tree element, returns an array of parameters
  * used to build an icon for that element.
  *
  * @param array $element An array representing an element in the grade_tree
  *
  * @return array
  */
 public function get_params_for_iconstr($element)
 {
     $strparams = new stdClass();
     $strparams->category = '';
     $strparams->itemname = '';
     $strparams->itemmodule = '';
     if (!method_exists($element['object'], 'get_name')) {
         return $strparams;
     }
     $strparams->itemname = html_to_text($element['object']->get_name());
     // If element name is categorytotal, get the name of the parent category
     if ($strparams->itemname == get_string('categorytotal', 'grades')) {
         $parent = $element['object']->get_parent_category();
         $strparams->category = $parent->get_name() . ' ';
     } else {
         $strparams->category = '';
     }
     $strparams->itemmodule = null;
     if (isset($element['object']->itemmodule)) {
         $strparams->itemmodule = $element['object']->itemmodule;
     }
     return $strparams;
 }
Example #23
0
 public function classify_response(array $response)
 {
     $parts = array();
     foreach ($this->places as $place => $group) {
         if (!array_key_exists($this->field($place), $response) || !$response[$this->field($place)]) {
             $parts[$place] = question_classified_response::no_response();
             continue;
         }
         $fieldname = $this->field($place);
         $choiceno = $this->choiceorder[$group][$response[$fieldname]];
         $choice = $this->choices[$group][$choiceno];
         $parts[$place] = new question_classified_response($choiceno, html_to_text($choice->text, 0, false), ($this->get_right_choice_for($place) == $response[$fieldname]) / count($this->places));
     }
     return $parts;
 }
Example #24
0
 /**
  * @param string response is a response.
  * @return formatted response
  */
 function format_response($response, $format)
 {
     $safeformatoptions = new stdClass();
     $safeformatoptions->para = false;
     return s(html_to_text(format_text($response, FORMAT_MOODLE, $safeformatoptions), 0, false));
 }
Example #25
0
/**
 * Given text in a variety of format codings, this function returns
 * the text as plain text suitable for plain email.
 *
 * @uses FORMAT_MOODLE
 * @uses FORMAT_HTML
 * @uses FORMAT_PLAIN
 * @uses FORMAT_WIKI
 * @uses FORMAT_MARKDOWN
 * @param string $text The text to be formatted. This is raw text originally from user input.
 * @param int $format Identifier of the text format to be used
 *            [FORMAT_MOODLE, FORMAT_HTML, FORMAT_PLAIN, FORMAT_WIKI, FORMAT_MARKDOWN]
 * @return string
 */
function format_text_email($text, $format)
{
    switch ($format) {
        case FORMAT_PLAIN:
            return $text;
            break;
        case FORMAT_WIKI:
            // there should not be any of these any more!
            $text = wikify_links($text);
            return strtr(strip_tags($text), array_flip(get_html_translation_table(HTML_ENTITIES)));
            break;
        case FORMAT_HTML:
            return html_to_text($text);
            break;
        case FORMAT_MOODLE:
        case FORMAT_MARKDOWN:
        default:
            $text = wikify_links($text);
            return strtr(strip_tags($text), array_flip(get_html_translation_table(HTML_ENTITIES)));
            break;
    }
}
Example #26
0
	/**
	 * Returns a plain text version of the email
	 * @return string
	 */
	function getTextBody() {
		if ($this->getBodyHtml()) {
			return html_to_text(html_entity_decode($this->getBodyHtml(),null, "UTF-8"));
		} else {
			return $this->getBodyPlain();
		}
	}
 protected function _plain_text($html)
 {
     if (!function_exists('html_to_text')) {
         $body = @html_entity_decode($html, ENT_QUOTES, $this->charset);
         // Added by Ivan Tcholakov, 28-JUL-2013.
         $body = preg_match('/\\<body.*?\\>(.*)\\<\\/body\\>/si', $body, $match) ? $match[1] : $body;
         $body = str_replace("\t", '', preg_replace('#<!--(.*)--\\>#', '', trim(strip_tags($body))));
         for ($i = 20; $i >= 3; $i--) {
             $body = str_replace(str_repeat("\n", $i), "\n\n", $body);
         }
         // Reduce multiple spaces
         $body = preg_replace('| +|', ' ', $body);
         return $body;
     }
     // Also, a special helper function based on Markdown or Textile libraries may be used.
     //
     // An example of Markdown-based implementation, see http://milianw.de/projects/markdownify/
     //
     // Make sure the class Markdownify_Extra is autoloaded (or simply loaded somehow).
     // Place in MY_html_helper.php the following function.
     //
     // function html_to_text($html) {
     //     static $parser;
     //     if (!isset($parser)) {
     //         $parser = new Markdownify_Extra();
     //         $parser->keepHTML = false;
     //     }
     //     return @ $parser->parseString($html);
     // }
     //
     return html_to_text($html);
 }
Example #28
0
function get_member_custom_property_value_for_listing($cp, $member_id, $cp_vals = null)
{
    if (is_null($cp_vals)) {
        $cp_vals = MemberCustomPropertyValues::getMemberCustomPropertyValues($member_id, $cp->getId());
    }
    $val_to_show = "";
    foreach ($cp_vals as $cp_val) {
        if (in_array($cp->getType(), array('contact', 'user')) && $cp_val instanceof MemberCustomPropertyValue) {
            $cp_contact = Contacts::findById($cp_val->getValue());
            if ($cp_contact instanceof Contact) {
                $cp_val->setValue($cp_contact->getObjectName());
            } else {
                $cp_val->setValue("");
            }
        }
        if ($cp->getType() == 'date' && $cp_val instanceof MemberCustomPropertyValue) {
            $format = user_config_option('date_format');
            Hook::fire("custom_property_date_format", null, $format);
            $tmp_date = DateTimeValueLib::dateFromFormatAndString(DATE_MYSQL, $cp_val->getValue());
            if (str_starts_with($cp_val->getValue(), EMPTY_DATE)) {
                $formatted = "";
            } else {
                if (str_ends_with($cp_val->getValue(), "00:00:00")) {
                    $formatted = $tmp_date->format(user_config_option('date_format'));
                } else {
                    $formatted = $tmp_date->format($format);
                }
            }
            $cp_val->setValue($formatted);
        }
        if ($cp->getType() == 'address' && $cp_val instanceof MemberCustomPropertyValue) {
            $values = str_replace("\\|", "%%_PIPE_%%", $cp_val->getValue());
            $exploded = explode("|", $values);
            foreach ($exploded as &$v) {
                $v = str_replace("%%_PIPE_%%", "|", $v);
                $v = str_replace("'", "\\'", $v);
            }
            if (count($exploded) > 0) {
                $address_type = array_var($exploded, 0, '');
                $street = array_var($exploded, 1, '');
                $city = array_var($exploded, 2, '');
                $state = array_var($exploded, 3, '');
                $country = array_var($exploded, 4, '');
                $zip_code = array_var($exploded, 5, '');
                $country_name = CountryCodes::getCountryNameByCode($country);
                $tmp = array();
                if ($street != '') {
                    $tmp[] = $street;
                }
                if ($city != '') {
                    $tmp[] = $city;
                }
                if ($state != '') {
                    $tmp[] = $state;
                }
                if ($zip_code != '') {
                    $tmp[] = $zip_code;
                }
                if ($country_name != '') {
                    $tmp[] = $country_name;
                }
                $cp_val->setValue(implode(' - ', $tmp));
            }
        }
        $val_to_show .= ($val_to_show == "" ? "" : ", ") . ($cp_val instanceof MemberCustomPropertyValue ? $cp_val->getValue() : "");
    }
    $val_to_show = html_to_text($val_to_show);
    return $val_to_show;
}
Example #29
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;
}
/**
 * This plugin sends users a welcome message after logging in
 * and notify a moderator a new user has been added
 * it has a settings page that allow you to configure the messages
 * send.
 *
 * @package    local
 * @subpackage welcome
 * @copyright  2015 Bas Brands, basbrands.nl, bas@sonsbeekmedia.nl
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
function send_welcome($user)
{
    global $CFG, $SITE;
    require_once $CFG->dirroot . '/local/welcome/locallib.php';
    $sender = get_admin();
    if (!empty($user->email)) {
        $config = get_config('local_welcome');
        $moderator = clone $sender;
        if (!empty($config->auth_plugins)) {
            $auths = explode(',', $config->auth_plugins);
            if (!in_array($user->auth, $auths)) {
                return '';
            }
        } else {
            return '';
        }
        $moderator->email = $config->moderator_email;
        $sender->email = $config->sender_email;
        $sender->firstname = $config->sender_firstname;
        $sender->lastname = $config->sender_lastname;
        $message_user_enabled = $config->message_user_enabled;
        $message_user = $config->message_user;
        $message_user_subject = $config->message_user_subject;
        $message_moderator_enabled = $config->message_moderator_enabled;
        $message_moderator = $config->message_moderator;
        $message_moderator_subject = $config->message_moderator_subject;
        $welcome = new local_welcome();
        $message_user = $welcome->replace_values($user, $message_user);
        $message_user_subject = $welcome->replace_values($user, $message_user_subject);
        $message_moderator = $welcome->replace_values($user, $message_moderator);
        $message_moderator_subject = $welcome->replace_values($user, $message_moderator_subject);
        if (!empty($message_user) && !empty($sender->email) && $message_user_enabled) {
            email_to_user($user, $sender, $message_user_subject, html_to_text($message_user), $message_user);
        }
        if (!empty($message_moderator) && !empty($sender->email) && $message_moderator_enabled) {
            email_to_user($moderator, $sender, $message_moderator_subject, html_to_text($message_moderator), $message_moderator);
        }
    }
}