Newer
Older
// 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
/**
* 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;
$subject = get_string('courserequest', 'local_hsh');
$message = get_string('courserequestnotifyemail', 'local_hsh', $data);
$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) {
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
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());
$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
$a->coursename = format_string($course->fullname, true, array('context' => context_course::instance($course->id)));
$a->responser = fullname($USER);
$a->fullname = fullname($user);
get_string('courseapprovedsubject', 'local_hsh', $a),
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);
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->courseid = empty($courseid) ? SITEID : $courseid;
$eventdata->component = $component;
$eventdata->name = $name;
$eventdata->userfrom = $fromuser;
$eventdata->userto = $touser;
$eventdata->subject = $subject;
$eventdata->fullmessage = $message;
$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);
* @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 .= 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;
}