Files
moodle/lib/classes/hub/publication.php
T
Marina Glancy da48baa2cd MDL-59495 moodlenet: move all moodlenet code into new namespace
Support for alternative hubs will be removed in 3.4
We can move all methods working with registration, course publishing and moodle.net
communication into separate namespace
2017-09-27 13:07:33 +08:00

409 lines
14 KiB
PHP

<?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");
make_temp_directory('backup');
$filename = md5(time() . '-' . $hubcourseid . '-'. $USER->id . '-'. random_string(20));
$path = $CFG->tempdir.'/backup/'.$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);
}
}