You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

409 lines
14 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/>.
/**
* Class publication
*
* @package core
* @copyright 2017 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\hub;
defined('MOODLE_INTERNAL') || die();
use moodle_exception;
use moodle_url;
use context_user;
use stdClass;
use html_writer;
/**
* Methods to work with site registration on moodle.net
*
* @package core
* @copyright 2017 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class publication {
/** @var Audience: educators */
const HUB_AUDIENCE_EDUCATORS = 'educators';
/** @var Audience: students */
const HUB_AUDIENCE_STUDENTS = 'students';
/** @var Audience: admins */
const HUB_AUDIENCE_ADMINS = 'admins';
/** @var Educational level: primary */
const HUB_EDULEVEL_PRIMARY = 'primary';
/** @var Educational level: secondary */
const HUB_EDULEVEL_SECONDARY = 'secondary';
/** @var Educational level: tertiary */
const HUB_EDULEVEL_TERTIARY = 'tertiary';
/** @var Educational level: government */
const HUB_EDULEVEL_GOVERNMENT = 'government';
/** @var Educational level: association */
const HUB_EDULEVEL_ASSOCIATION = 'association';
/** @var Educational level: corporate */
const HUB_EDULEVEL_CORPORATE = 'corporate';
/** @var Educational level: other */
const HUB_EDULEVEL_OTHER = 'other';
/**
* Retrieve all the sorted course subjects
*
* @return array $subjects
*/
public static function get_sorted_subjects() {
$subjects = get_string_manager()->load_component_strings('edufields', current_language());
// Sort the subjects.
$return = [];
asort($subjects);
foreach ($subjects as $key => $option) {
$keylength = strlen($key);
if ($keylength == 12) {
$return[$key] = $option; // We want only selectable categories.
}
}
return $return;
}
/**
* Get all publication for a course
*
* @param int $courseid local course id
* @return array of publication
*/
public static function get_course_publications($courseid) {
global $DB;
$sql = 'SELECT cp.id, cp.status, cp.timechecked, cp.timepublished, rh.hubname,
rh.huburl, cp.courseid, cp.enrollable, cp.hubcourseid
FROM {course_published} cp, {registration_hubs} rh
WHERE cp.huburl = rh.huburl and cp.courseid = :courseid and rh.huburl = :huburl
ORDER BY cp.enrollable DESC, rh.hubname, cp.timepublished';
$params = array('courseid' => $courseid, 'huburl' => HUB_MOODLEORGHUBURL);
$records = $DB->get_records_sql($sql, $params);
// Add links for publications that are listed.
foreach ($records as $id => $record) {
if ($record->status) {
$records[$id]->link = new moodle_url(HUB_MOODLEORGHUBURL, ['courseid' => $record->hubcourseid]);
}
}
return $records;
}
/**
* Load publication information from local db
*
* @param int $id
* @param int $courseid if specified publication will be checked that it is in the current course
* @param int $strictness
* @return stdClass
*/
public static function get_publication($id, $courseid = 0, $strictness = IGNORE_MISSING) {
global $DB;
if (!$id && $strictness != MUST_EXIST) {
return false;
}
$params = ['id' => $id, 'huburl' => HUB_MOODLEORGHUBURL];
if ($courseid) {
$params['courseid'] = $courseid;
}
return $DB->get_record('course_published', $params, '*', $strictness);
}
/**
* Update a course publication
* @param stdClass $publication
*/
protected static function update_publication($publication) {
global $DB;
$DB->update_record('course_published', $publication);
}
/**
* Check all courses published from this site if they have been approved
*/
public static function request_status_update() {
global $DB;
list($sitecourses, $coursetotal) = api::get_courses('', 1, 1, ['allsitecourses' => 1]);
// Update status for all these course.
foreach ($sitecourses as $sitecourse) {
// Get the publication from the hub course id.
$publication = $DB->get_record('course_published', ['hubcourseid' => $sitecourse['id']]);
if (!empty($publication)) {
$publication->status = $sitecourse['privacy'];
$publication->timechecked = time();
self::update_publication($publication);
} else {
$msgparams = new stdClass();
$msgparams->id = $sitecourse['id'];
$msgparams->hubname = html_writer::tag('a', 'Moodle.net', array('href' => HUB_MOODLEORGHUBURL));
\core\notification::add(get_string('detectednotexistingpublication', 'hub', $msgparams)); // TODO action?
}
}
}
/**
* Unpublish a course
*
* @param stdClass $publication
*/
public static function unpublish($publication) {
global $DB;
// Unpublish the publication by web service.
api::unregister_courses($publication->hubcourseid);
// Delete the publication from the database.
$DB->delete_records('course_published', array('id' => $publication->id));
// Add confirmation message.
$course = get_course($publication->courseid);
$context = \context_course::instance($course->id);
$publication->courseshortname = format_string($course->shortname, true, ['context' => $context]);
$publication->hubname = 'Moodle.net';
\core\notification::add(get_string('courseunpublished', 'hub', $publication), \core\output\notification::NOTIFY_SUCCESS);
}
/**
* Publish a course
*
* @param \stdClass $courseinfo
* @param \stored_file[] $files
*/
public static function publish_course($courseinfo, $files) {
global $DB;
// Register course and get id of the course on moodle.net ($hubcourseid).
$courseid = $courseinfo->sitecourseid;
try {
$hubcourseid = api::register_course($courseinfo);
} catch (Exception $e) {
throw new moodle_exception('errorcoursepublish', 'hub',
new moodle_url('/course/view.php', array('id' => $courseid)), $e->getMessage());
}
// Insert/update publication record in the local DB.
$publication = $DB->get_record('course_published', array('hubcourseid' => $hubcourseid, 'huburl' => HUB_MOODLEORGHUBURL));
if ($publication) {
$DB->update_record('course_published', ['id' => $publication->id, 'timepublished' => time()]);
} else {
$publication = new stdClass();
$publication->huburl = HUB_MOODLEORGHUBURL;
$publication->courseid = $courseid;
$publication->hubcourseid = $hubcourseid;
$publication->enrollable = (int)$courseinfo->enrollable;
$publication->timepublished = time();
$publication->id = $DB->insert_record('course_published', $publication);
}
// Send screenshots.
if ($files) {
$screenshotnumber = $courseinfo->screenshots - count($files);
foreach ($files as $file) {
$screenshotnumber++;
api::add_screenshot($hubcourseid, $file, $screenshotnumber);
}
}
return $hubcourseid;
}
/**
* Delete all publications
*
* @param int $advertised search for advertised courses
* @param int $shared search for shared courses
* @throws moodle_exception
*/
public static function delete_all_publications($advertised = true, $shared = true) {
global $DB;
if (!$advertised && !$shared) {
// Nothing to do.
return true;
}
$params = ['huburl' => HUB_MOODLEORGHUBURL];
if (!$advertised || !$shared) {
// Retrieve ONLY advertised or ONLY shared.
$params['enrollable'] = $advertised ? 1 : 0;
}
if (!$publications = $DB->get_records('course_published', $params)) {
// Nothing to unpublish.
return true;
}
foreach ($publications as $publication) {
$hubcourseids[] = $publication->hubcourseid;
}
api::unregister_courses($hubcourseids);
// Delete the published courses from local db.
$DB->delete_records('course_published', $params);
return true;
}
/**
* Get an array of all block instances for a given context
* @param int $contextid a context id
* @return array of block instances.
*/
public static function get_block_instances_by_context($contextid) {
global $DB;
return $DB->get_records('block_instances', array('parentcontextid' => $contextid), 'blockname');
}
/**
* List of available educational levels
*
* @param bool $any add option for "Any" (for search forms)
* @return array
*/
public static function educational_level_options($any = false) {
$options = array();
if ($any) {
$options['all'] = get_string('any');
}
$options[self::HUB_EDULEVEL_PRIMARY] = get_string('edulevelprimary', 'hub');
$options[self::HUB_EDULEVEL_SECONDARY] = get_string('edulevelsecondary', 'hub');
$options[self::HUB_EDULEVEL_TERTIARY] = get_string('eduleveltertiary', 'hub');
$options[self::HUB_EDULEVEL_GOVERNMENT] = get_string('edulevelgovernment', 'hub');
$options[self::HUB_EDULEVEL_ASSOCIATION] = get_string('edulevelassociation', 'hub');
$options[self::HUB_EDULEVEL_CORPORATE] = get_string('edulevelcorporate', 'hub');
$options[self::HUB_EDULEVEL_OTHER] = get_string('edulevelother', 'hub');
return $options;
}
/**
* List of available audience options
*
* @param bool $any add option for "Any" (for search forms)
* @return array
*/
public static function audience_options($any = false) {
$options = array();
if ($any) {
$options['all'] = get_string('any');
}
$options[self::HUB_AUDIENCE_EDUCATORS] = get_string('audienceeducators', 'hub');
$options[self::HUB_AUDIENCE_STUDENTS] = get_string('audiencestudents', 'hub');
$options[self::HUB_AUDIENCE_ADMINS] = get_string('audienceadmins', 'hub');
return $options;
}
/**
* Search for courses
*
* For the list of fields returned for each course see {@link communication::get_courses}
*
* @param string $search search string
* @param bool $downloadable true - return downloadable courses, false - return enrollable courses
* @param array|\stdClass $options other options from the list of allowed options:
* 'ids', 'sitecourseids', 'coverage', 'licenceshortname', 'subject', 'audience',
* 'educationallevel', 'language', 'orderby', 'givememore', 'allsitecourses'
* @return array of two elements: [$courses, $coursetotal]
*/
public static function search($search, $downloadable, $options) {
try {
return api::get_courses($search, $downloadable, !$downloadable, $options);
} catch (moodle_exception $e) {
\core\notification::add(get_string('errorcourselisting', 'block_community', $e->getMessage()),
\core\output\notification::NOTIFY_ERROR);
return [[], 0];
}
}
/**
* Retrieves information about published course
*
* For the list of fields returned for the course see {@link communication::get_courses}
*
* @param stdClass $publication
* @return array|null
*/
public static function get_published_course($publication) {
try {
list($courses, $unused) = api::get_courses('', !$publication->enrollable,
$publication->enrollable, ['ids' => [$publication->hubcourseid], 'allsitecourses' => 1]);
return reset($courses);
} catch (\Exception $e) {
\core\notification::add(get_string('errorcourseinfo', 'hub', $e->getMessage()),
\core\output\notification::NOTIFY_ERROR);
}
return null;
}
/**
* Downloads course backup and stores it in the user private files
*
* @param int $hubcourseid
* @param string $coursename
* @return array
*/
public static function download_course_backup($hubcourseid, $coursename) {
global $CFG, $USER;
require_once($CFG->libdir . "/filelib.php");
$backuptempdir = make_backup_temp_directory('');
$filename = md5(time() . '-' . $hubcourseid . '-'. $USER->id . '-'. random_string(20));
$path = $backuptempdir.'/'.$filename.".mbz";
api::download_course_backup($hubcourseid, $path);
$fs = get_file_storage();
$record = new stdClass();
$record->contextid = context_user::instance($USER->id)->id;
$record->component = 'user';
$record->filearea = 'private';
$record->itemid = 0;
$record->filename = urlencode($coursename).'_'.time().".mbz";
$record->filepath = '/downloaded_backup/';
if (!$fs->file_exists($record->contextid, $record->component,
$record->filearea, 0, $record->filepath, $record->filename)) {
$fs->create_file_from_pathname($record, $path);
}
return [$record->filepath . $record->filename, $filename];
}
/**
* Uploads a course backup
*
* @param int $hubcourseid id of the published course on moodle.net, it must be published from this site
* @param \stored_file $backupfile
*/
public static function upload_course_backup($hubcourseid, \stored_file $backupfile) {
api::upload_course_backup($hubcourseid, $backupfile);
}
}