Select Git revision
-
Elke Kreim authoredElke Kreim authored
lib.php 21.41 KiB
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Library of useful functions
*
* @copyright 1999 Martin Dougiamas http://dougiamas.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @package core_course
*/
defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir . '/moodlelib.php');
/**
* This class pertains to course requests and contains methods associated with
* create, approving, and removing course requests.
*
* Please note we do not allow embedded images here because there is no context
* to store them with proper access control.
*
* @copyright 2009 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 2.0
*
* @property-read int $id
* @property-read string $fullname
* @property-read string $shortname
* @property-read string $summary
* @property-read int $summaryformat
* @property-read int $summarytrust
* @property-read string $reason
* @property-read int $requester
*/
class course_request_hsh
{
/**
* This is the stdClass that stores the properties for the course request
* and is externally accessed through the __get magic method
* @var stdClass
*/
protected $properties;
/**
* An array of options for the summary editor used by course request forms.
* This is initially set by {@link summary_editor_options()}
* @var array
* @static
*/
protected static $summaryeditoroptions;
/**
* Static function to prepare the summary editor for working with a course
* request.
*
* @static
* @param null|stdClass $data Optional, an object containing the default values
* for the form, these may be modified when preparing the
* editor so this should be called before creating the form
* @return stdClass An object that can be used to set the default values for
* an mforms form
*/
public static function prepare($data = null)
{
if ($data === null) {
$data = new stdClass;
}
$data = file_prepare_standard_editor($data, 'summary', self::summary_editor_options());
return $data;
}
/**
* Static function to create a new course request when passed an array of properties
* for it.
*
* This function also handles saving any files that may have been used in the editor
*
* @static
* @param stdClass $data
* @return course_request_hsh The newly created course request
*/
public static function create($data) {
global $USER, $DB, $CFG;
$data->requester = $USER->id;
// Setting the default category if none set.
if (empty($data->category) || !empty($CFG->lockrequestcategory)) {
$data->category = $CFG->defaultrequestcategory;
}
// Summary is a required field so copy the text over
$data->summary = $data->summary_editor['text'];
$data->summaryformat = $data->summary_editor['format'];
// > HsH
$data->fullname = \course_request_hsh::get_hsh_name(
$data->fullname,
$data->teachername,
$data->customfield_semester,
false
);
$data->shortname = \course_request_hsh::get_hsh_name(
$data->shortname,
$data->teachername,
$data->customfield_semester,
true
);
if (isset($data->consult)) {
$data->reason .= '</br> ' . get_string('elcconsult', 'local_hsh');
}
// < HsH
$data->id = $DB->insert_record('local_hsh_course_request', $data);
// Create a new course_request object and return it
$request = new course_request_hsh($data);
// Notify the admin if required.
if ($users = get_users_from_config($CFG->courserequestnotify, 'moodle/site:approvecourse')) {
$data->user = fullname($USER);
$data->link = $CFG->wwwroot . "/local/hsh/pending.php";
$data->email = $USER->email;
$cats = \core_course_category::make_categories_list('', 0, ' / ');
$data->category = $cats[$data->category];
$subject = get_string('courserequest', 'local_hsh');
$message = get_string('courserequestnotifyemail', 'local_hsh', $data);
foreach ($users as $user) {
$request->notify('moodle', $user, $USER, 'courserequested', $subject, $message);
}
}
return $request;
}
/**
* Returns an array of options to use with a summary editor
*
* @return array An array of options to use with the editor
* @uses course_request_hsh::$summaryeditoroptions
*/
public static function summary_editor_options() {
global $CFG;
if (self::$summaryeditoroptions === null) {
self::$summaryeditoroptions = array('maxfiles' => 0, 'maxbytes' => 0);
}
return self::$summaryeditoroptions;
}
/**
* Loads the properties for this course request object. Id is required and if
* only id is provided then we load the rest of the properties from the database
*
* @param stdClass|int $properties Either an object containing properties
* or the course_request id to load
*/
public function __construct($properties) {
global $DB;
if (empty($properties->id)) {
if (empty($properties)) {
throw new coding_exception('You must provide a course request id when creating a course_request object');
}
$id = $properties;
$properties = new stdClass;
$properties->id = (int)$id;
unset($id);
}
if (empty($properties->requester)) {
if (!($this->properties = $DB->get_record('local_hsh_course_request', array('id' => $properties->id)))) {
throw new \moodle_exception('unknowncourserequest');
}
} else {
$this->properties = $properties;
}
$this->properties->collision = null;
}
/**
* Returns the requested property
*
* @param string $key
* @return mixed
*/
public function __get($key) {
return $this->properties->$key;
}
/**
* Override this to ensure empty($request->blah) calls return a reliable answer...
*
* This is required because we define the __get method
*
* @param mixed $key
* @return bool True is it not empty, false otherwise
*/
public function __isset($key) {
return (!empty($this->properties->$key));
}
/**
* Returns the user who requested this course
*
* Uses a static var to cache the results and cut down the number of db queries
*
* @staticvar array $requesters An array of cached users
* @return stdClass The user who requested the course
*/
public function get_requester() {
global $DB;
static $requesters = array();
if (!array_key_exists($this->properties->requester, $requesters)) {
$requesters[$this->properties->requester] = $DB->get_record('user', array('id' => $this->properties->requester));
}
return $requesters[$this->properties->requester];
}
/**
* Checks that the shortname used by the course does not conflict with any other
* courses that exist
*
* @param string|null $shortnamemark The string to append to the requests shortname
* should a conflict be found
* @return bool true is there is a conflict, false otherwise
*/
public function check_shortname_collision($shortnamemark = '[*]') {
global $DB;
if ($this->properties->collision !== null) {
return $this->properties->collision;
}
if (empty($this->properties->shortname)) {
debugging('Attempting to check a course request shortname before it has been set', DEBUG_DEVELOPER);
$this->properties->collision = false;
} else if ($DB->record_exists('course', array('shortname' => $this->properties->shortname))) {
if (!empty($shortnamemark)) {
$this->properties->shortname .= ' ' . $shortnamemark;
}
$this->properties->collision = true;
} else {
$this->properties->collision = false;
}
return $this->properties->collision;
}
/**
* Checks user capability to approve a requested course
*
* If course was requested without category for some reason (might happen if $CFG->defaultrequestcategory is
* misconfigured), we check capabilities 'moodle/site:approvecourse' and 'moodle/course:changecategory'.
*
* @return bool
*/
public function can_approve() {
global $CFG;
$category = null;
if ($this->properties->category) {
$category = core_course_category::get($this->properties->category, IGNORE_MISSING);
} else if ($CFG->defaultrequestcategory) {
$category = core_course_category::get($CFG->defaultrequestcategory, IGNORE_MISSING);
}
if ($category) {
return has_capability('moodle/site:approvecourse', $category->get_context());
}
// We can not determine the context where the course should be created. The approver should have
// both capabilities to approve courses and change course category in the system context.
return has_all_capabilities(['moodle/site:approvecourse', 'moodle/course:changecategory'], context_system::instance());
}
/**
* Returns the category where this course request should be created
*
* Note that we don't check here that user has a capability to view
* hidden categories if he has capabilities 'moodle/site:approvecourse' and
* 'moodle/course:changecategory'
*
* @return core_course_category
*/
public function get_category()
{
global $CFG;
if ($this->properties->category && ($category = core_course_category::get($this->properties->category, IGNORE_MISSING))) {
return $category;
} else if ($CFG->defaultrequestcategory &&
($category = core_course_category::get($CFG->defaultrequestcategory, IGNORE_MISSING))) {
return $category;
} else {
return core_course_category::get_default();
}
}
/**
* This function approves the request turning it into a course
*
* This function converts the course request into a course, at the same time
* transferring any files used in the summary to the new course and then removing
* the course request and the files associated with it.
*
* @return int The id of the course that was created from this request
*/
public function approve()
{
global $CFG, $DB, $USER;
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
$user = $DB->get_record('user', array('id' => $this->properties->requester, 'deleted' => 0), '*', MUST_EXIST);
$courseconfig = get_config('moodlecourse');
// Transfer appropriate settings
$data = clone($this->properties);
unset($data->id);
unset($data->reason);
unset($data->requester);
// Set category
$category = $this->get_category();
$data->category = $category->id;
// Set misc settings
$data->requested = 1;
// Apply course default settings
$data->format = $courseconfig->format;
$data->newsitems = $courseconfig->newsitems;
$data->showgrades = $courseconfig->showgrades;
$data->showreports = $courseconfig->showreports;
$data->maxbytes = $courseconfig->maxbytes;
$data->groupmode = $courseconfig->groupmode;
$data->groupmodeforce = $courseconfig->groupmodeforce;
$data->visible = $courseconfig->visible;
$data->visibleold = $data->visible;
$data->lang = $courseconfig->lang;
$data->enablecompletion = $courseconfig->enablecompletion;
$data->numsections = $courseconfig->numsections;
$data->startdate = usergetmidnight(time());
if ($courseconfig->courseenddateenabled) {
$data->enddate = usergetmidnight(time()) + $courseconfig->courseduration;
}
list($data->fullname, $data->shortname) = restore_dbops::calculate_course_names(0, $data->fullname, $data->shortname);
$course = create_course($data);
$context = context_course::instance($course->id, MUST_EXIST);
// add enrol instances
if (!$DB->record_exists('enrol', array('courseid' => $course->id, 'enrol' => 'manual'))) {
if ($manual = enrol_get_plugin('manual')) {
$manual->add_default_instance($course);
}
}
// > HsH peter werner - set password for self enrolment from request.php
if (!empty($data->password)) {
if ($self = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'self', 'status' => 0))) {
$self->password = $data->password;
$DB->update_record('enrol', $self);
}
}
// < HsH
// enrol default roles from plugin config settings
$default_roles=get_config('local_hsh', 'defaultrole');
if (!empty($default_roles) && !isguestuser($user) && !is_enrolled($context, $user, 'moodle/role:assign')) {
$roles = explode(',', $default_roles);
foreach($roles as $role) {
enrol_try_internal_enrol($course->id, $user->id, $role);
}
} elseif (!empty($CFG->creatornewroleid) && !isguestuser($user) && !is_enrolled($context, $user, 'moodle/role:assign')) {
enrol_try_internal_enrol($course->id, $user->id, $CFG->creatornewroleid);
} // enrol the requester as teacher if necessary
$this->delete();
$a = new stdClass();
$a->coursename = format_string($course->fullname, true, array('context' => context_course::instance($course->id)));
$a->url = $CFG->wwwroot . '/course/view.php?id=' . $course->id;
$a->responser = fullname($USER);
$a->email = $USER->email;
$a->telefon = $USER->phone1;
$a->fullname = fullname($user);
$messageplain = $this->get_message_plain($a);
$this->notify(
'local_hsh',
$user,
$USER,
'courserequestapproved_hsh',
get_string('courseapprovedsubject', 'local_hsh', $a),
$messageplain,
$course->id
);
return $course->id;
}
/**
* Reject a course request
*
* This function rejects a course request, emailing the requesting user the
* provided notice and then removing the request from the database
*
* @param string $notice The message to display to the user
*/
public function reject($notice)
{
global $USER, $DB;
$user = $DB->get_record('user', array('id' => $this->properties->requester), '*', MUST_EXIST);
$this->notify(
'local_hsh',
$user,
$USER,
'courserequestrejected_hsh',
get_string('courserejectsubject', 'local_hsh'),
get_string('courserejectemail', 'local_hsh', $notice)
);
$this->delete();
}
/**
* Deletes the course request and any associated files
*/
public function delete()
{
global $DB;
$DB->delete_records('local_hsh_course_request', array('id' => $this->properties->id));
}
/**
* Send a message from one user to another using events_trigger
*
* @param object $touser
* @param object $fromuser
* @param string $name
* @param string $subject
* @param string $message
* @param int|null $courseid
*/
protected function notify($component, $touser, $fromuser, $name, $subject, $message, $courseid = null) {
$eventdata = new \core\message\message();
$eventdata->courseid = empty($courseid) ? SITEID : $courseid;
$eventdata->component = $component;
$eventdata->name = $name;
$eventdata->userfrom = $fromuser;
$eventdata->userto = $touser;
$eventdata->subject = $subject;
$eventdata->fullmessage = $message;
$eventdata->fullmessageformat = FORMAT_PLAIN;
$eventdata->fullmessagehtml = '';
$eventdata->smallmessage = '';
$eventdata->notification = 1;
message_send($eventdata);
}
/**
* Checks if current user can request a course in this context
*
* @param context $context
* @return bool
*/
public static function can_request(context $context)
{
global $CFG;
if (empty($CFG->enablecourserequests)) {
return false;
}
if (has_capability('moodle/course:create', $context)) {
return false;
}
if ($context instanceof context_system) {
$defaultcontext = context_coursecat::instance($CFG->defaultrequestcategory, IGNORE_MISSING);
return $defaultcontext &&
has_capability('local/hsh:request', $defaultcontext);
} else if ($context instanceof context_coursecat) {
if (!$CFG->lockrequestcategory || $CFG->defaultrequestcategory == $context->instanceid) {
return has_capability('local/hsh:request', $context);
}
}
return false;
}
/**
*
* @param type $coursename short or fullname
* @param type $teacher
* @param type $semesterValue intvalue from db
* @return type
*/
public static function get_hsh_name($coursename, $teacher, $semesterValue, $short = true)
{
$semesterName = \customfield_semester\data_controller::get_name_for_semester((int)$semesterValue);
if ($semesterValue == 1) {
return $coursename . ", " . $teacher;
} else {
if ($short) {
$exploded = explode(" ", $semesterName);
return $coursename . ", " . $exploded[1] . ", " . $teacher;
}
return $coursename . ", " . $semesterName . ", " . $teacher;
}
}
/**
* replaces coursecategory items
* @static
* @return array
*/
public static function get_short_categories_list()
{
$courselist = \core_course_category::make_categories_list('', 0, '$$$');
foreach ($courselist as &$actCourse) {
$actCourseArr = explode('$$$', $actCourse);
$actCourseSize = sizeof($actCourseArr);
if ($actCourseSize > 1) {
$actCourse = '';
for ($i = 0; $i < $actCourseSize - 1; $i++) {
$actCourse .= '../ ';
}
$actCourse .= $actCourseArr[$actCourseSize - 1];
}
}
return $courselist;
}
protected function get_message_plain($a) {
$message = get_string('address', 'local_hsh', $a) . "\r\n";
$message .= "\r\n";
$message .= get_string('courseapproved', 'local_hsh', $a) . "\r\n";
$message .= "\r\n";
$message .= get_string('tocourse_plain', 'local_hsh', $a) . "\r\n";
$message .= "\r\n";
if (!empty($this->properties->coursecopyurl)) {
$message .= get_string('coursecopyinform', 'local_hsh', $a) . "\r\n";
$message .= "\r\n";
}
// $message .= get_string('questionhint', 'local_hsh') . ' ' . get_string('questionhintmail', 'local_hsh') . "." . "\r\n";
$message .= get_string('questionhint1', 'local_hsh') . "\r\n";
// $message .= get_string('questionhint2', 'local_hsh') . "\r\n";
// $message .= get_string('questionhint3', 'local_hsh') . "\r\n";
$message .= "\r\n";
// $message .= get_string('consultinghint', 'local_hsh') . "\r\n";
$message .= "\r\n";
$message .= get_string('greetings', 'local_hsh') . "\r\n";
// $message .= "\r\n";
$message .= "Servicezentrum Lehre" . "\r\n";
// $message .= $a->email . "\r\n";
// $message .= $a->telefon . "\r\n";
$message .= "\r\n";
$message .= "\r\n";
$message .= get_string('institute1', 'local_hsh') . "\r\n";
// $message .= get_string('institute2', 'local_hsh') . "\r\n";
$message .= get_string('ou1', 'local_hsh') . "\r\n";
$message .= get_string('ou2', 'local_hsh') . "\r\n";
// $message .= get_string('street', 'local_hsh') . "\r\n";
// $message .= get_string('place', 'local_hsh') . "\r\n";
$message .= "\r\n";
$message .= get_string('email', 'local_hsh') . ': ' . get_string('elcmailaddress', 'local_hsh') . "\r\n";
$message .= get_string('elcphone', 'local_hsh');
return $message;
}
} // End HsH