MDL-59495 moodlenet: move all moodlenet code into new namespace
authorMarina Glancy <marina@moodle.com>
Tue, 12 Sep 2017 07:15:06 +0000 (15:15 +0800)
committerMarina Glancy <marina@moodle.com>
Wed, 27 Sep 2017 05:07:33 +0000 (13:07 +0800)
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

admin/registration/forms.php
admin/registration/lib.php
course/publish/forms.php
course/publish/lib.php
lang/en/hub.php
lib/classes/hub/api.php [new file with mode: 0644]
lib/classes/hub/course_publication_form.php [new file with mode: 0644]
lib/classes/hub/publication.php [new file with mode: 0644]
lib/classes/hub/registration.php [new file with mode: 0644]
lib/classes/hub/site_registration_form.php [new file with mode: 0644]
lib/classes/hub/site_unregistration_form.php [new file with mode: 0644]

index 0d70879..f685364 100644 (file)
@@ -20,7 +20,7 @@
 //                                                                       //
 ///////////////////////////////////////////////////////////////////////////
 
-/*
+/**
  * @package    moodle
  * @subpackage registration
  * @author     Jerome Mouneyrac <jerome@mouneyrac.com>
  * The forms needed by registration pages.
  */
 
+defined('MOODLE_INTERNAL') || die();
 
-require_once($CFG->libdir . '/formslib.php');
-require_once($CFG->dirroot . '/' . $CFG->admin . '/registration/lib.php');
-
-/**
- * This form display a unregistration form.
- */
-class site_unregistration_form extends moodleform {
-
-    public function definition() {
-        $mform = & $this->_form;
-        $mform->addElement('header', 'site', get_string('unregister', 'hub'));
-
-        $huburl = $this->_customdata['huburl'];
-        $hubname = $this->_customdata['hubname'];
-
-        $unregisterlabel = get_string('unregister', 'hub');
-        $mform->addElement('checkbox', 'unpublishalladvertisedcourses', '',
-                ' ' . get_string('unpublishalladvertisedcourses', 'hub'));
-        $mform->setType('unpublishalladvertisedcourses', PARAM_INT);
-        $mform->addElement('checkbox', 'unpublishalluploadedcourses', '',
-                ' ' . get_string('unpublishalluploadedcourses', 'hub'));
-        $mform->setType('unpublishalluploadedcourses', PARAM_INT);
-
-        $mform->addElement('hidden', 'confirm', 1);
-        $mform->setType('confirm', PARAM_INT);
-        $mform->addElement('hidden', 'unregistration', 1);
-        $mform->setType('unregistration', PARAM_INT);
-        $mform->addElement('hidden', 'huburl', $huburl);
-        $mform->setType('huburl', PARAM_URL);
-        $mform->addElement('hidden', 'hubname', $hubname);
-        $mform->setType('hubname', PARAM_TEXT);
-
-        $this->add_action_buttons(true, $unregisterlabel);
-    }
-
-}
-
-/**
- * This form display a clean registration data form.
- */
-class site_clean_registration_data_form extends moodleform {
-
-    public function definition() {
-        $mform = & $this->_form;
-        $mform->addElement('header', 'site', get_string('unregister', 'hub'));
-
-        $huburl = $this->_customdata['huburl'];
-        $hubname = $this->_customdata['hubname'];
-
-
-        $unregisterlabel = get_string('forceunregister', 'hub');
-        $mform->addElement('static', '', get_string('warning', 'hub'), get_string('forceunregisterconfirmation', 'hub', $hubname));
-
-        $mform->addElement('hidden', 'confirm', 1);
-        $mform->setType('confirm', PARAM_INT);
-        $mform->addElement('hidden', 'unregistration', 1);
-        $mform->setType('unregistration', PARAM_INT);
-        $mform->addElement('hidden', 'cleanregdata', 1);
-        $mform->setType('cleanregdata', PARAM_INT);
-        $mform->addElement('hidden', 'huburl', $huburl);
-        $mform->setType('huburl', PARAM_URL);
-        $mform->addElement('hidden', 'hubname', $hubname);
-        $mform->setType('hubname', PARAM_TEXT);
-
-        $this->add_action_buttons(true, $unregisterlabel);
-    }
-
-}
-
-/**
- * This form display a hub selector.
- * The hub list is retrieved from Moodle.org hub directory.
- * Also displayed, a text field to enter private hub url + its password
- */
-class hub_selector_form extends moodleform {
-
-    public function definition() {
-        global $CFG, $OUTPUT;
-        $mform = & $this->_form;
-        $mform->addElement('header', 'site', get_string('selecthub', 'hub'));
-
-        //retrieve the hub list on the hub directory by web service
-        $function = 'hubdirectory_get_hubs';
-        $params = array();
-        $serverurl = HUB_HUBDIRECTORYURL . "/local/hubdirectory/webservice/webservices.php";
-        require_once($CFG->dirroot . "/webservice/xmlrpc/lib.php");
-        $xmlrpcclient = new webservice_xmlrpc_client($serverurl, 'publichubdirectory');
-        try {
-            $hubs = $xmlrpcclient->call($function, $params);
-        } catch (Exception $e) {
-            $error = $OUTPUT->notification(get_string('errorhublisting', 'hub', $e->getMessage()));
-            $mform->addElement('static', 'errorhub', '', $error);
-            $hubs = array();
-        }
-
-        //remove moodle.org from the hub list
-        foreach ($hubs as $key => $hub) {
-            if ($hub['url'] == HUB_MOODLEORGHUBURL || $hub['url'] == HUB_OLDMOODLEORGHUBURL) {
-                unset($hubs[$key]);
-            }
-        }
-
-        //Public hub list
-        $options = array();
-        foreach ($hubs as $hub) {
-            //to not display a name longer than 100 character (too big)
-            if (core_text::strlen($hub['name']) > 100) {
-                $hubname = core_text::substr($hub['name'], 0, 100);
-                $hubname = $hubname . "...";
-            } else {
-                $hubname = $hub['name'];
-            }
-            $options[$hub['url']] = $hubname;
-            $mform->addElement('hidden', clean_param($hub['url'], PARAM_ALPHANUMEXT), $hubname);
-            $mform->setType(clean_param($hub['url'], PARAM_ALPHANUMEXT), PARAM_ALPHANUMEXT);
-        }
-        if (!empty($hubs)) {
-            $mform->addElement('select', 'publichub', get_string('publichub', 'hub'),
-                    $options, array("size" => 15));
-            $mform->setType('publichub', PARAM_URL);
-        }
-
-        $mform->addElement('static', 'or', '', get_string('orenterprivatehub', 'hub'));
-
-        //Private hub
-        $mform->addElement('text', 'unlistedurl', get_string('privatehuburl', 'hub'),
-                array('class' => 'registration_textfield'));
-        $mform->setType('unlistedurl', PARAM_URL);
-        $mform->addElement('text', 'password', get_string('password'),
-                array('class' => 'registration_textfield'));
-        $mform->setType('password', PARAM_RAW);
-
-        $this->add_action_buttons(false, get_string('selecthub', 'hub'));
-    }
-
-    /**
-     * Check the unlisted URL is a URL
-     */
-    function validation($data, $files) {
-        global $CFG;
-        $errors = parent::validation($data, $files);
-
-        $unlistedurl = $this->_form->_submitValues['unlistedurl'];
-
-        if (empty($unlistedurl)) {
-            $errors['unlistedurl'] = get_string('badurlformat', 'hub');
-        }
-
-        return $errors;
-    }
-
-}
-
-/**
- * The site registration form. Information will be sent to a given hub.
- */
-class site_registration_form extends moodleform {
-
-    public function definition() {
-        global $CFG, $DB;
-
-        $strrequired = get_string('required');
-        $mform = & $this->_form;
-        $huburl = $this->_customdata['huburl'];
-        $hubname = $this->_customdata['hubname'];
-        $password = $this->_customdata['password'];
-        $admin = get_admin();
-        $site = get_site();
-
-        //retrieve config for this hub and set default if they don't exist
-        $cleanhuburl = clean_param($huburl, PARAM_ALPHANUMEXT);
-        $sitename = get_config('hub', 'site_name_' . $cleanhuburl);
-        if ($sitename === false) {
-            $sitename = format_string($site->fullname, true, array('context' => context_course::instance(SITEID)));
-        }
-        $sitedescription = get_config('hub', 'site_description_' . $cleanhuburl);
-        if ($sitedescription === false) {
-            $sitedescription = $site->summary;
-        }
-        $contactname = get_config('hub', 'site_contactname_' . $cleanhuburl);
-        if ($contactname === false) {
-            $contactname = fullname($admin, true);
-        }
-        $contactemail = get_config('hub', 'site_contactemail_' . $cleanhuburl);
-        if ($contactemail === false) {
-            $contactemail = $admin->email;
-        }
-        $contactphone = get_config('hub', 'site_contactphone_' . $cleanhuburl);
-        if ($contactphone === false) {
-            $contactphone = $admin->phone1;
-        }
-        $imageurl = get_config('hub', 'site_imageurl_' . $cleanhuburl);
-        $privacy = get_config('hub', 'site_privacy_' . $cleanhuburl);
-        $address = get_config('hub', 'site_address_' . $cleanhuburl);
-        if ($address === false) {
-            $address = '';
-        }
-        $region = get_config('hub', 'site_region_' . $cleanhuburl);
-        $country = get_config('hub', 'site_country_' . $cleanhuburl);
-        if (empty($country)) {
-            $country = $admin->country ?: $CFG->country;
-        }
-        $language = get_config('hub', 'site_language_' . $cleanhuburl);
-        if ($language === false) {
-            $language = explode('_', current_language())[0];
-        }
-        $geolocation = get_config('hub', 'site_geolocation_' . $cleanhuburl);
-        if ($geolocation === false) {
-            $geolocation = '';
-        }
-        $contactable = get_config('hub', 'site_contactable_' . $cleanhuburl);
-        $emailalert = get_config('hub', 'site_emailalert_' . $cleanhuburl);
-        $emailalert = ($emailalert === false || $emailalert) ? 1 : 0;
-        $coursesnumber = get_config('hub', 'site_coursesnumber_' . $cleanhuburl);
-        $usersnumber = get_config('hub', 'site_usersnumber_' . $cleanhuburl);
-        $roleassignmentsnumber = get_config('hub', 'site_roleassignmentsnumber_' . $cleanhuburl);
-        $postsnumber = get_config('hub', 'site_postsnumber_' . $cleanhuburl);
-        $questionsnumber = get_config('hub', 'site_questionsnumber_' . $cleanhuburl);
-        $resourcesnumber = get_config('hub', 'site_resourcesnumber_' . $cleanhuburl);
-        $badgesnumber = get_config('hub', 'site_badges_' . $cleanhuburl);
-        $issuedbadgesnumber = get_config('hub', 'site_issuedbadges_' . $cleanhuburl);
-        $mediancoursesize = get_config('hub', 'site_mediancoursesize_' . $cleanhuburl);
-        $participantnumberaveragecfg = get_config('hub', 'site_participantnumberaverage_' . $cleanhuburl);
-        $modulenumberaveragecfg = get_config('hub', 'site_modulenumberaverage_' . $cleanhuburl);
-        // Mobile related information.
-        $mobileservicesenabled = get_config('hub', 'site_mobileservicesenabled_' . $cleanhuburl);
-        $mobilenotificationsenabled = get_config('hub', 'site_mobilenotificationsenabled_' . $cleanhuburl);
-        $registereduserdevices = get_config('hub', 'site_registereduserdevices_' . $cleanhuburl);
-        $registeredactiveuserdevices = get_config('hub', 'site_registeredactiveuserdevices_' . $cleanhuburl);
-
-        //hidden parameters
-        $mform->addElement('hidden', 'huburl', $huburl);
-        $mform->setType('huburl', PARAM_URL);
-        $mform->addElement('hidden', 'hubname', $hubname);
-        $mform->setType('hubname', PARAM_TEXT);
-        $mform->addElement('hidden', 'password', $password);
-        $mform->setType('password', PARAM_RAW);
-
-        //the input parameters
-        $mform->addElement('header', 'moodle', get_string('registrationinfo', 'hub'));
-
-        $mform->addElement('text', 'name', get_string('sitename', 'hub'),
-                array('class' => 'registration_textfield'));
-        $mform->addRule('name', $strrequired, 'required', null, 'client');
-        $mform->setType('name', PARAM_TEXT);
-        $mform->setDefault('name', $sitename);
-        $mform->addHelpButton('name', 'sitename', 'hub');
-
-        $options = array();
-        $registrationmanager = new registration_manager();
-        $options[HUB_SITENOTPUBLISHED] = $registrationmanager->get_site_privacy_string(HUB_SITENOTPUBLISHED);
-        $options[HUB_SITENAMEPUBLISHED] = $registrationmanager->get_site_privacy_string(HUB_SITENAMEPUBLISHED);
-        $options[HUB_SITELINKPUBLISHED] = $registrationmanager->get_site_privacy_string(HUB_SITELINKPUBLISHED);
-        $mform->addElement('select', 'privacy', get_string('siteprivacy', 'hub'), $options);
-        $mform->setDefault('privacy', $privacy);
-        $mform->setType('privacy', PARAM_ALPHA);
-        $mform->addHelpButton('privacy', 'privacy', 'hub');
-        unset($options);
-
-        $mform->addElement('textarea', 'description', get_string('sitedesc', 'hub'),
-                array('rows' => 8, 'cols' => 41));
-        $mform->addRule('description', $strrequired, 'required', null, 'client');
-        $mform->setDefault('description', $sitedescription);
-        $mform->setType('description', PARAM_TEXT);
-        $mform->addHelpButton('description', 'sitedesc', 'hub');
-
-        $languages = get_string_manager()->get_list_of_languages();
-        core_collator::asort($languages);
-        $mform->addElement('select', 'language', get_string('sitelang', 'hub'),
-                $languages);
-        $mform->setType('language', PARAM_ALPHANUMEXT);
-        $mform->addHelpButton('language', 'sitelang', 'hub');
-        $mform->setDefault('language', $language);
-
-        $mform->addElement('textarea', 'address', get_string('postaladdress', 'hub'),
-                array('rows' => 4, 'cols' => 41));
-        $mform->setType('address', PARAM_TEXT);
-        $mform->setDefault('address', $address);
-        $mform->addHelpButton('address', 'postaladdress', 'hub');
-
-        //TODO: use the region array I generated
-//        $mform->addElement('select', 'region', get_string('selectaregion'), array('-' => '-'));
-//        $mform->setDefault('region', $region);
-        $mform->addElement('hidden', 'regioncode', '-');
-        $mform->setType('regioncode', PARAM_ALPHANUMEXT);
-
-        $countries = ['' => ''] + get_string_manager()->get_list_of_countries();
-        $mform->addElement('select', 'countrycode', get_string('sitecountry', 'hub'), $countries);
-        $mform->setDefault('countrycode', $country);
-        $mform->setType('countrycode', PARAM_ALPHANUMEXT);
-        $mform->addHelpButton('countrycode', 'sitecountry', 'hub');
-        $mform->addRule('countrycode', $strrequired, 'required', null, 'client');
-
-        $mform->addElement('text', 'geolocation', get_string('sitegeolocation', 'hub'),
-                array('class' => 'registration_textfield'));
-        $mform->setDefault('geolocation', $geolocation);
-        $mform->setType('geolocation', PARAM_RAW);
-        $mform->addHelpButton('geolocation', 'sitegeolocation', 'hub');
-
-        $mform->addElement('text', 'contactname', get_string('siteadmin', 'hub'),
-                array('class' => 'registration_textfield'));
-        $mform->addRule('contactname', $strrequired, 'required', null, 'client');
-        $mform->setType('contactname', PARAM_TEXT);
-        $mform->setDefault('contactname', $contactname);
-        $mform->addHelpButton('contactname', 'siteadmin', 'hub');
-
-        $mform->addElement('text', 'contactphone', get_string('sitephone', 'hub'),
-                array('class' => 'registration_textfield'));
-        $mform->setType('contactphone', PARAM_TEXT);
-        $mform->setDefault('contactphone', $contactphone);
-        $mform->addHelpButton('contactphone', 'sitephone', 'hub');
-        $mform->setForceLtr('contactphone');
-
-        $mform->addElement('text', 'contactemail', get_string('siteemail', 'hub'),
-                array('class' => 'registration_textfield'));
-        $mform->addRule('contactemail', $strrequired, 'required', null, 'client');
-        $mform->setType('contactemail', PARAM_EMAIL);
-        $mform->setDefault('contactemail', $contactemail);
-        $mform->addHelpButton('contactemail', 'siteemail', 'hub');
-
-        $options = array();
-        $options[0] = get_string("registrationcontactno");
-        $options[1] = get_string("registrationcontactyes");
-        $mform->addElement('select', 'contactable', get_string('siteregistrationcontact', 'hub'), $options);
-        $mform->setDefault('contactable', $contactable);
-        $mform->setType('contactable', PARAM_INT);
-        $mform->addHelpButton('contactable', 'siteregistrationcontact', 'hub');
-        unset($options);
-
-        $options = array();
-        $options[0] = get_string("registrationno");
-        $options[1] = get_string("registrationyes");
-        $mform->addElement('select', 'emailalert', get_string('siteregistrationemail', 'hub'), $options);
-        $mform->setDefault('emailalert', $emailalert);
-        $mform->setType('emailalert', PARAM_INT);
-        $mform->addHelpButton('emailalert', 'siteregistrationemail', 'hub');
-        unset($options);
-
-        //TODO site logo
-        $mform->addElement('hidden', 'imageurl', ''); //TODO: temporary
-        $mform->setType('imageurl', PARAM_URL);
-
-        $mform->addElement('static', 'urlstring', get_string('siteurl', 'hub'), $CFG->wwwroot);
-        $mform->addHelpButton('urlstring', 'siteurl', 'hub');
-
-        $mform->addElement('static', 'versionstring', get_string('siteversion', 'hub'), $CFG->version);
-        $mform->addElement('hidden', 'moodleversion', $CFG->version);
-        $mform->setType('moodleversion', PARAM_INT);
-        $mform->addHelpButton('versionstring', 'siteversion', 'hub');
-
-        $mform->addElement('static', 'releasestring', get_string('siterelease', 'hub'), $CFG->release);
-        $mform->addElement('hidden', 'moodlerelease', $CFG->release);
-        $mform->setType('moodlerelease', PARAM_TEXT);
-        $mform->addHelpButton('releasestring', 'siterelease', 'hub');
-
-        /// Display statistic that are going to be retrieve by the hub
-        $coursecount = $DB->count_records('course') - 1;
-        $usercount = $DB->count_records('user', array('deleted' => 0));
-        $roleassigncount = $DB->count_records('role_assignments');
-        $postcount = $DB->count_records('forum_posts');
-        $questioncount = $DB->count_records('question');
-        $resourcecount = $DB->count_records('resource');
-        require_once($CFG->dirroot . "/course/lib.php");
-        $participantnumberaverage = number_format(average_number_of_participants(), 2);
-        $modulenumberaverage = number_format(average_number_of_courses_modules(), 2);
-        require_once($CFG->libdir . '/badgeslib.php');
-        $badges = $DB->count_records_select('badge', 'status <> ' . BADGE_STATUS_ARCHIVED);
-        $issuedbadges = $DB->count_records('badge_issued');
-        // Mobile related information.
-        $ismobileenabled = false;
-        $aremobilenotificationsenabled = false;
-        $registereduserdevicescount = 0;
-        $registeredactiveuserdevicescount = 0;
-        if (!empty($CFG->enablewebservices) && !empty($CFG->enablemobilewebservice)) {
-            $ismobileenabled = true;
-            $registereduserdevicescount = $DB->count_records('user_devices');
-            $airnotifierextpath = $CFG->dirroot . '/message/output/airnotifier/externallib.php';
-            if (file_exists($airnotifierextpath)) { // Maybe some one uninstalled the plugin.
-                require_once($airnotifierextpath);
-                $aremobilenotificationsenabled = (bool) message_airnotifier_external::is_system_configured();
-                $registeredactiveuserdevicescount = $DB->count_records('message_airnotifier_devices', array('enable' => 1));
-            }
-        }
-
-        if (HUB_MOODLEORGHUBURL != $huburl) {
-            $mform->addElement('checkbox', 'courses', get_string('sendfollowinginfo', 'hub'),
-                    " " . get_string('coursesnumber', 'hub', $coursecount));
-            $mform->setDefault('courses', $coursesnumber != -1);
-            $mform->setType('courses', PARAM_INT);
-            $mform->addHelpButton('courses', 'sendfollowinginfo', 'hub');
-
-            $mform->addElement('checkbox', 'users', '',
-                    " " . get_string('usersnumber', 'hub', $usercount));
-            $mform->setDefault('users', $usersnumber != -1);
-            $mform->setType('users', PARAM_INT);
-
-            $mform->addElement('checkbox', 'roleassignments', '',
-                    " " . get_string('roleassignmentsnumber', 'hub', $roleassigncount));
-            $mform->setDefault('roleassignments', $roleassignmentsnumber != -1);
-            $mform->setType('roleassignments', PARAM_INT);
-
-            $mform->addElement('checkbox', 'posts', '',
-                    " " . get_string('postsnumber', 'hub', $postcount));
-            $mform->setDefault('posts', $postsnumber != -1);
-            $mform->setType('posts', PARAM_INT);
-
-            $mform->addElement('checkbox', 'questions', '',
-                    " " . get_string('questionsnumber', 'hub', $questioncount));
-            $mform->setDefault('questions', $questionsnumber != -1);
-            $mform->setType('questions', PARAM_INT);
-
-            $mform->addElement('checkbox', 'resources', '',
-                    " " . get_string('resourcesnumber', 'hub', $resourcecount));
-            $mform->setDefault('resources', $resourcesnumber != -1);
-            $mform->setType('resources', PARAM_INT);
-
-            $mform->addElement('checkbox', 'badges', '',
-                    " " . get_string('badgesnumber', 'hub', $badges));
-            $mform->setDefault('badges', $badgesnumber != -1);
-            $mform->setType('badges', PARAM_INT);
-
-            $mform->addElement('checkbox', 'issuedbadges', '',
-                    " " . get_string('issuedbadgesnumber', 'hub', $issuedbadges));
-            $mform->setDefault('issuedbadges', $issuedbadgesnumber != -1);
-            $mform->setType('issuedbadges', PARAM_INT);
-
-            $mform->addElement('checkbox', 'participantnumberaverage', '',
-                    " " . get_string('participantnumberaverage', 'hub', $participantnumberaverage));
-            $mform->setDefault('participantnumberaverage', $participantnumberaveragecfg != -1);
-            $mform->setType('participantnumberaverage', PARAM_FLOAT);
-
-            $mform->addElement('checkbox', 'modulenumberaverage', '',
-                    " " . get_string('modulenumberaverage', 'hub', $modulenumberaverage));
-            $mform->setDefault('modulenumberaverage', $modulenumberaveragecfg != -1);
-            $mform->setType('modulenumberaverage', PARAM_FLOAT);
-
-            $mobileservicestatus = $ismobileenabled ? 'yes' : 'no';
-            $mform->addElement('checkbox', 'mobileservicesenabled', '',
-                    " " . get_string('mobileservicesenabled', 'hub', $mobileservicestatus));
-            $mform->setDefault('mobileservicesenabled', $mobileservicesenabled != -1);
-            $mform->setType('mobileservicesenabled', PARAM_INT);
-
-            $mobilenotificationsstatus = $aremobilenotificationsenabled ? 'yes' : 'no';
-            $mform->addElement('checkbox', 'mobilenotificationsenabled', '',
-                    " " . get_string('mobilenotificationsenabled', 'hub', $mobilenotificationsstatus));
-            $mform->setDefault('mobilenotificationsenabled', $mobilenotificationsenabled != -1);
-            $mform->setType('mobilenotificationsenabled', PARAM_INT);
-
-            $mform->addElement('checkbox', 'registereduserdevices', '',
-                    " " . get_string('registereduserdevices', 'hub', $registereduserdevicescount));
-            $mform->setDefault('registereduserdevices', $registereduserdevices != -1);
-            $mform->setType('registereduserdevices', PARAM_INT);
-
-            $mform->addElement('checkbox', 'registeredactiveuserdevices', '',
-                    " " . get_string('registeredactiveuserdevices', 'hub', $registeredactiveuserdevicescount));
-            $mform->setDefault('registeredactiveuserdevices', $registeredactiveuserdevices != -1);
-            $mform->setType('registeredactiveuserdevices', PARAM_INT);
-        } else {
-            $mform->addElement('static', 'courseslabel', get_string('sendfollowinginfo', 'hub'),
-                    " " . get_string('coursesnumber', 'hub', $coursecount));
-            $mform->addElement('hidden', 'courses', 1);
-            $mform->setType('courses', PARAM_INT);
-            $mform->addHelpButton('courseslabel', 'sendfollowinginfo', 'hub');
-
-            $mform->addElement('static', 'userslabel', '',
-                    " " . get_string('usersnumber', 'hub', $usercount));
-            $mform->addElement('hidden', 'users', 1);
-            $mform->setType('users', PARAM_INT);
-
-            $mform->addElement('static', 'roleassignmentslabel', '',
-                    " " . get_string('roleassignmentsnumber', 'hub', $roleassigncount));
-            $mform->addElement('hidden', 'roleassignments', 1);
-            $mform->setType('roleassignments', PARAM_INT);
-
-            $mform->addElement('static', 'postslabel', '',
-                    " " . get_string('postsnumber', 'hub', $postcount));
-            $mform->addElement('hidden', 'posts', 1);
-            $mform->setType('posts', PARAM_INT);
-
-            $mform->addElement('static', 'questionslabel', '',
-                    " " . get_string('questionsnumber', 'hub', $questioncount));
-            $mform->addElement('hidden', 'questions', 1);
-            $mform->setType('questions', PARAM_INT);
-
-            $mform->addElement('static', 'resourceslabel', '',
-                    " " . get_string('resourcesnumber', 'hub', $resourcecount));
-            $mform->addElement('hidden', 'resources', 1);
-            $mform->setType('resources', PARAM_INT);
-
-            $mform->addElement('static', 'badgeslabel', '',
-                    " " . get_string('badgesnumber', 'hub', $badges));
-            $mform->addElement('hidden', 'badges', 1);
-            $mform->setType('badges', PARAM_INT);
-
-            $mform->addElement('static', 'issuedbadgeslabel', '',
-                    " " . get_string('issuedbadgesnumber', 'hub', $issuedbadges));
-            $mform->addElement('hidden', 'issuedbadges', true);
-            $mform->setType('issuedbadges', PARAM_INT);
-
-            $mform->addElement('static', 'participantnumberaveragelabel', '',
-                    " " . get_string('participantnumberaverage', 'hub', $participantnumberaverage));
-            $mform->addElement('hidden', 'participantnumberaverage', 1);
-            $mform->setType('participantnumberaverage', PARAM_FLOAT);
-
-            $mform->addElement('static', 'modulenumberaveragelabel', '',
-                    " " . get_string('modulenumberaverage', 'hub', $modulenumberaverage));
-            $mform->addElement('hidden', 'modulenumberaverage', 1);
-            $mform->setType('modulenumberaverage', PARAM_FLOAT);
-
-            $mobileservicestatus = $ismobileenabled ? 'yes' : 'no';
-            $mform->addElement('static', 'mobileservicesenabledlabel', '',
-                    " " . get_string('mobileservicesenabled', 'hub', $mobileservicestatus));
-            $mform->addElement('hidden', 'mobileservicesenabled', 1);
-            $mform->setType('mobileservicesenabled', PARAM_INT);
-
-            $mobilenotificationsstatus = $aremobilenotificationsenabled ? 'yes' : 'no';
-            $mform->addElement('static', 'mobilenotificationsenabledlabel', '',
-                    " " . get_string('mobilenotificationsenabled', 'hub', $mobilenotificationsstatus));
-            $mform->addElement('hidden', 'mobilenotificationsenabled', 1);
-            $mform->setType('mobilenotificationsenabled', PARAM_INT);
-
-            $mform->addElement('static', 'registereduserdeviceslabel', '',
-                    " " . get_string('registereduserdevices', 'hub', $registereduserdevicescount));
-            $mform->addElement('hidden', 'registereduserdevices', 1);
-            $mform->setType('registereduserdevices', PARAM_INT);
-
-            $mform->addElement('static', 'registeredactiveuserdeviceslabel', '',
-                    " " . get_string('registeredactiveuserdevices', 'hub', $registeredactiveuserdevicescount));
-            $mform->addElement('hidden', 'registeredactiveuserdevices', 1);
-            $mform->setType('registeredactiveuserdevices', PARAM_INT);
-        }
-
-        //check if it's a first registration or update
-        $hubregistered = $registrationmanager->get_registeredhub($huburl);
-
-        if (!empty($hubregistered)) {
-            $buttonlabel = get_string('updatesite', 'hub',
-                            !empty($hubname) ? $hubname : $huburl);
-            $mform->addElement('hidden', 'update', true);
-            $mform->setType('update', PARAM_BOOL);
-        } else {
-            $buttonlabel = get_string('registersite', 'hub',
-                            !empty($hubname) ? $hubname : $huburl);
-        }
-
-        $this->add_action_buttons(false, $buttonlabel);
-    }
-
-}
-
+debugging('Support for alternative hubs has been removed from Moodle in 3.4. For communication with moodle.net ' .
+    'see lib/classes/moodlenet/ .', DEBUG_DEVELOPER);
index 8d1f8db..72330f6 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
-
-
-
-//// SITE PRIVACY /////
-
-/**
- * Site privacy: private
- */
-define('HUB_SITENOTPUBLISHED', 'notdisplayed');
-
-/**
- * Site privacy: public
- */
-define('HUB_SITENAMEPUBLISHED', 'named');
-
-/**
- * Site privacy: public and global
- */
-define('HUB_SITELINKPUBLISHED', 'linked');
-
-/**
- *
- * Site registration library
- *
- * @package   course
- * @copyright 2010 Moodle Pty Ltd (http://moodle.com)
- * @author    Jerome Mouneyrac
- * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class registration_manager {
-
-    /**
-     * Automatically update the registration on all hubs
-     */
-    public function cron() {
-        global $CFG;
-        if (extension_loaded('xmlrpc')) {
-            $function = 'hub_update_site_info';
-            require_once($CFG->dirroot . "/webservice/xmlrpc/lib.php");
-
-            // Update all hubs where the site is registered.
-            $hubs = $this->get_registered_on_hubs();
-            if (empty($hubs)) {
-                mtrace(get_string('registrationwarning', 'admin'));
-            }
-            foreach ($hubs as $hub) {
-                // Update the registration.
-                $siteinfo = $this->get_site_info($hub->huburl);
-                $params = array('siteinfo' => $siteinfo);
-                $serverurl = $hub->huburl . "/local/hub/webservice/webservices.php";
-                $xmlrpcclient = new webservice_xmlrpc_client($serverurl, $hub->token);
-                try {
-                    $result = $xmlrpcclient->call($function, $params);
-                    $this->update_registeredhub($hub); // To update timemodified.
-                    mtrace(get_string('siteupdatedcron', 'hub', $hub->hubname));
-                } catch (Exception $e) {
-                    $errorparam = new stdClass();
-                    $errorparam->errormessage = $e->getMessage();
-                    $errorparam->hubname = $hub->hubname;
-                    mtrace(get_string('errorcron', 'hub', $errorparam));
-                }
-            }
-        } else {
-            mtrace(get_string('errorcronnoxmlrpc', 'hub'));
-        }
-    }
-
-    /**
-     * Return the site secret for a given hub
-     * site identifier is assigned to Mooch
-     * each hub has a unique and personal site secret.
-     * @param string $huburl
-     * @return string site secret
-     */
-    public function get_site_secret_for_hub($huburl) {
-        global $DB;
-
-        $existingregistration = $DB->get_record('registration_hubs',
-                    array('huburl' => $huburl));
-
-        if (!empty($existingregistration)) {
-            return $existingregistration->secret;
-        }
-
-        if ($huburl == HUB_MOODLEORGHUBURL) {
-            $siteidentifier =  get_site_identifier();
-        } else {
-            $siteidentifier = random_string(32) . $_SERVER['HTTP_HOST'];
-        }
-
-        return $siteidentifier;
-
-    }
-
-    /**
-     * When the site register on a hub, he must call this function
-     * @param object $hub where the site is registered on
-     * @return integer id of the record
-     */
-    public function add_registeredhub($hub) {
-        global $DB;
-        $hub->timemodified = time();
-        $id = $DB->insert_record('registration_hubs', $hub);
-        return $id;
-    }
-
-    /**
-     * When a site unregister from a hub, he must call this function
-     * @param string $huburl the huburl to delete
-     */
-    public function delete_registeredhub($huburl) {
-        global $DB;
-        $DB->delete_records('registration_hubs', array('huburl' => $huburl));
-    }
-
-    /**
-     * Get a hub on which the site is registered for a given url or token
-     * Mostly use to check if the site is registered on a specific hub
-     * @param string $huburl
-     * @param string $token
-     * @return object the  hub
-     */
-    public function get_registeredhub($huburl = null, $token = null) {
-        global $DB;
-
-        $params = array();
-        if (!empty($huburl)) {
-            $params['huburl'] = $huburl;
-        }
-        if (!empty($token)) {
-            $params['token'] = $token;
-        }
-        $params['confirmed'] = 1;
-        $token = $DB->get_record('registration_hubs', $params);
-        return $token;
-    }
-
-    /**
-     * Get the hub which has not confirmed that the site is registered on,
-     * but for which a request has been sent
-     * @param string $huburl
-     * @return object the  hub
-     */
-    public function get_unconfirmedhub($huburl) {
-        global $DB;
-
-        $params = array();
-        $params['huburl'] = $huburl;
-        $params['confirmed'] = 0;
-        $token = $DB->get_record('registration_hubs', $params);
-        return $token;
-    }
-
-    /**
-     * Update a registered hub (mostly use to update the confirmation status)
-     * @param object $hub the hub
-     */
-    public function update_registeredhub($hub) {
-        global $DB;
-        $hub->timemodified = time();
-        $DB->update_record('registration_hubs', $hub);
-    }
-
-    /**
-     * Return all hubs where the site is registered
-     */
-    public function get_registered_on_hubs() {
-        global $DB;
-        $hubs = $DB->get_records('registration_hubs', array('confirmed' => 1));
-        return $hubs;
-    }
-
-    /**
-     * Return site information for a specific hub
-     * @param string $huburl
-     * @return array site info
-     */
-    public function get_site_info($huburl) {
-        global $CFG, $DB;
-
-        $siteinfo = array();
-        $cleanhuburl = clean_param($huburl, PARAM_ALPHANUMEXT);
-        $siteinfo['name'] = get_config('hub', 'site_name_' . $cleanhuburl);
-        $siteinfo['description'] = get_config('hub', 'site_description_' . $cleanhuburl);
-        $siteinfo['contactname'] = get_config('hub', 'site_contactname_' . $cleanhuburl);
-        $siteinfo['contactemail'] = get_config('hub', 'site_contactemail_' . $cleanhuburl);
-        $siteinfo['contactphone'] = get_config('hub', 'site_contactphone_' . $cleanhuburl);
-        $siteinfo['imageurl'] = get_config('hub', 'site_imageurl_' . $cleanhuburl);
-        $siteinfo['privacy'] = get_config('hub', 'site_privacy_' . $cleanhuburl);
-        $siteinfo['street'] = get_config('hub', 'site_address_' . $cleanhuburl);
-        $siteinfo['regioncode'] = get_config('hub', 'site_region_' . $cleanhuburl);
-        $siteinfo['countrycode'] = get_config('hub', 'site_country_' . $cleanhuburl);
-        $siteinfo['geolocation'] = get_config('hub', 'site_geolocation_' . $cleanhuburl);
-        $siteinfo['contactable'] = get_config('hub', 'site_contactable_' . $cleanhuburl);
-        $siteinfo['emailalert'] = get_config('hub', 'site_emailalert_' . $cleanhuburl);
-        if (get_config('hub', 'site_coursesnumber_' . $cleanhuburl) == -1) {
-            $coursecount = -1;
-        } else {
-            $coursecount = $DB->count_records('course') - 1;
-        }
-        $siteinfo['courses'] = $coursecount;
-        if (get_config('hub', 'site_usersnumber_' . $cleanhuburl) == -1) {
-            $usercount = -1;
-        } else {
-            $usercount = $DB->count_records('user', array('deleted' => 0));
-        }
-        $siteinfo['users'] = $usercount;
-
-        if (get_config('hub', 'site_roleassignmentsnumber_' . $cleanhuburl) == -1) {
-            $roleassigncount = -1;
-        } else {
-            $roleassigncount = $DB->count_records('role_assignments');
-        }
-        $siteinfo['enrolments'] = $roleassigncount;
-        if (get_config('hub', 'site_postsnumber_' . $cleanhuburl) == -1) {
-            $postcount = -1;
-        } else {
-            $postcount = $DB->count_records('forum_posts');
-        }
-        $siteinfo['posts'] = $postcount;
-        if (get_config('hub', 'site_questionsnumber_' . $cleanhuburl) == -1) {
-            $questioncount = -1;
-        } else {
-            $questioncount = $DB->count_records('question');
-        }
-        $siteinfo['questions'] = $questioncount;
-        if (get_config('hub', 'site_resourcesnumber_' . $cleanhuburl) == -1) {
-            $resourcecount = -1;
-        } else {
-            $resourcecount = $DB->count_records('resource');
-        }
-        $siteinfo['resources'] = $resourcecount;
-        // Badge statistics.
-        require_once($CFG->libdir . '/badgeslib.php');
-        if (get_config('hub', 'site_badges_' . $cleanhuburl) == -1) {
-            $badges = -1;
-        } else {
-            $badges = $DB->count_records_select('badge', 'status <> ' . BADGE_STATUS_ARCHIVED);
-        }
-        $siteinfo['badges'] = $badges;
-        if (get_config('hub', 'site_issuedbadges_' . $cleanhuburl) == -1) {
-            $issuedbadges = -1;
-        } else {
-            $issuedbadges = $DB->count_records('badge_issued');
-        }
-        $siteinfo['issuedbadges'] = $issuedbadges;
-        //TODO
-        require_once($CFG->dirroot . "/course/lib.php");
-        if (get_config('hub', 'site_participantnumberaverage_' . $cleanhuburl) == -1) {
-            $participantnumberaverage = -1;
-        } else {
-            $participantnumberaverage = average_number_of_participants();
-        }
-        $siteinfo['participantnumberaverage'] = $participantnumberaverage;
-        if (get_config('hub', 'site_modulenumberaverage_' . $cleanhuburl) == -1) {
-            $modulenumberaverage = -1;
-        } else {
-            $modulenumberaverage = average_number_of_courses_modules();
-        }
-        $siteinfo['modulenumberaverage'] = $modulenumberaverage;
-        $siteinfo['language'] = get_config('hub', 'site_language_' . $cleanhuburl);
-        $siteinfo['moodleversion'] = $CFG->version;
-        $siteinfo['moodlerelease'] = $CFG->release;
-        $siteinfo['url'] = $CFG->wwwroot;
-        // Mobile related information.
-        $siteinfo['mobileservicesenabled'] = 0;
-        $siteinfo['mobilenotificationsenabled'] = 0;
-        $siteinfo['registereduserdevices'] = 0;
-        $siteinfo['registeredactiveuserdevices'] = 0;
-        if (!empty($CFG->enablewebservices) && !empty($CFG->enablemobilewebservice)) {
-            $siteinfo['mobileservicesenabled'] = 1;
-            $siteinfo['registereduserdevices'] = $DB->count_records('user_devices');
-            $airnotifierextpath = $CFG->dirroot . '/message/output/airnotifier/externallib.php';
-            if (file_exists($airnotifierextpath)) { // Maybe some one uninstalled the plugin.
-                require_once($airnotifierextpath);
-                $siteinfo['mobilenotificationsenabled'] = message_airnotifier_external::is_system_configured();
-                $siteinfo['registeredactiveuserdevices'] = $DB->count_records('message_airnotifier_devices', array('enable' => 1));
-            }
-        }
-
-        return $siteinfo;
-    }
-
-    /**
-     * Retrieve the site privacy string matching the define value
-     * @param string $privacy must match the define into moodlelib.php
-     * @return string
-     */
-    public function get_site_privacy_string($privacy) {
-        switch ($privacy) {
-            case HUB_SITENOTPUBLISHED:
-                $privacystring = get_string('siteprivacynotpublished', 'hub');
-                break;
-            case HUB_SITENAMEPUBLISHED:
-                $privacystring = get_string('siteprivacypublished', 'hub');
-                break;
-            case HUB_SITELINKPUBLISHED:
-                $privacystring = get_string('siteprivacylinked', 'hub');
-                break;
-        }
-        if (empty($privacystring)) {
-            throw new moodle_exception('unknownprivacy');
-        }
-        return $privacystring;
-    }
-
-}
-?>
+defined('MOODLE_INTERNAL') || die();
index 45ccbfb..b512115 100644 (file)
@@ -20,7 +20,7 @@
 //                                                                       //
 ///////////////////////////////////////////////////////////////////////////
 
-/*
+/**
  * @package    course
  * @subpackage publish
  * @author     Jerome Mouneyrac <jerome@mouneyrac.com>
  * The forms used for course publication
  */
 
+defined('MOODLE_INTERNAL') || die();
 
-require_once($CFG->libdir . '/formslib.php');
-require_once($CFG->dirroot . "/" . $CFG->admin . "/registration/lib.php");
-require_once($CFG->dirroot . "/course/publish/lib.php");
-
-/*
- * Hub selector to choose on which hub we want to publish.
- */
-
-class hub_publish_selector_form extends moodleform {
-
-    public function definition() {
-        global $CFG;
-        $mform = & $this->_form;
-        $share = $this->_customdata['share'];
-
-        $mform->addElement('header', 'site', get_string('selecthub', 'hub'));
-
-        $mform->addElement('static', 'info', '', get_string('selecthubinfo', 'hub') . html_writer::empty_tag('br'));
-
-        $registrationmanager = new registration_manager();
-        $registeredhubs = $registrationmanager->get_registered_on_hubs();
-
-        //Public hub list
-        $options = array();
-        foreach ($registeredhubs as $hub) {
-
-            $hubname = $hub->hubname;
-            $mform->addElement('hidden', clean_param($hub->huburl, PARAM_ALPHANUMEXT), $hubname);
-            $mform->setType(clean_param($hub->huburl, PARAM_ALPHANUMEXT), PARAM_ALPHANUMEXT);
-            if (empty($hubname)) {
-                $hubname = $hub->huburl;
-            }
-            $mform->addElement('radio', 'huburl', null, ' ' . $hubname, $hub->huburl);
-            if ($hub->huburl == HUB_MOODLEORGHUBURL) {
-                $mform->setDefault('huburl', $hub->huburl);
-            }
-        }
-
-        $mform->addElement('hidden', 'id', $this->_customdata['id']);
-        $mform->setType('id', PARAM_INT);
-
-        if ($share) {
-            $buttonlabel = get_string('shareonhub', 'hub');
-            $mform->addElement('hidden', 'share', true);
-            $mform->setType('share', PARAM_BOOL);
-        } else {
-            $buttonlabel = get_string('advertiseonhub', 'hub');
-            $mform->addElement('hidden', 'advertise', true);
-            $mform->setType('advertise', PARAM_BOOL);
-        }
-
-        $this->add_action_buttons(false, $buttonlabel);
-    }
-
-}
-
-/*
- * Course publication form
- */
-
-class course_publication_form extends moodleform {
-
-    public function definition() {
-        global $CFG, $DB, $USER, $OUTPUT;
-
-        $strrequired = get_string('required');
-        $mform = & $this->_form;
-        $huburl = $this->_customdata['huburl'];
-        $hubname = $this->_customdata['hubname'];
-        $course = $this->_customdata['course'];
-        $advertise = $this->_customdata['advertise'];
-        $share = $this->_customdata['share'];
-        $page = $this->_customdata['page'];
-        $site = get_site();
-
-        //hidden parameters
-        $mform->addElement('hidden', 'huburl', $huburl);
-        $mform->setType('huburl', PARAM_URL);
-        $mform->addElement('hidden', 'hubname', $hubname);
-        $mform->setType('hubname', PARAM_TEXT);
-
-        //check on the hub if the course has already been published
-        $registrationmanager = new registration_manager();
-        $registeredhub = $registrationmanager->get_registeredhub($huburl);
-        $publicationmanager = new course_publish_manager();
-        $publications = $publicationmanager->get_publications($registeredhub->huburl, $course->id, $advertise);
-
-        if (!empty($publications)) {
-            //get the last publication of this course
-            $publication = array_pop($publications);
-
-            $function = 'hub_get_courses';
-            $options = new stdClass();
-            $options->ids = array($publication->hubcourseid);
-            $options->allsitecourses = 1;
-            $params = array('search' => '', 'downloadable' => $share,
-                'enrollable' => !$share, 'options' => $options);
-            $serverurl = $huburl . "/local/hub/webservice/webservices.php";
-            require_once($CFG->dirroot . "/webservice/xmlrpc/lib.php");
-            $xmlrpcclient = new webservice_xmlrpc_client($serverurl, $registeredhub->token);
-            try {
-                $result = $xmlrpcclient->call($function, $params);
-                $publishedcourses = $result['courses'];
-            } catch (Exception $e) {
-                $error = $OUTPUT->notification(get_string('errorcourseinfo', 'hub', $e->getMessage()));
-                $mform->addElement('static', 'errorhub', '', $error);
-            }
-        }
-
-        if (!empty($publishedcourses)) {
-            $publishedcourse = $publishedcourses[0];
-            $hubcourseid = $publishedcourse['id'];
-            $defaultfullname = $publishedcourse['fullname'];
-            $defaultshortname = $publishedcourse['shortname'];
-            $defaultsummary = $publishedcourse['description'];
-            $defaultlanguage = $publishedcourse['language'];
-            $defaultpublishername = $publishedcourse['publishername'];
-            $defaultpublisheremail = $publishedcourse['publisheremail'];
-            $defaultcontributornames = $publishedcourse['contributornames'];
-            $defaultcoverage = $publishedcourse['coverage'];
-            $defaultcreatorname = $publishedcourse['creatorname'];
-            $defaultlicenceshortname = $publishedcourse['licenceshortname'];
-            $defaultsubject = $publishedcourse['subject'];
-            $defaultaudience = $publishedcourse['audience'];
-            $defaulteducationallevel = $publishedcourse['educationallevel'];
-            $defaultcreatornotes = $publishedcourse['creatornotes'];
-            $defaultcreatornotesformat = $publishedcourse['creatornotesformat'];
-            $screenshotsnumber = $publishedcourse['screenshots'];
-            $privacy = $publishedcourse['privacy'];
-            if (($screenshotsnumber > 0) and !empty($privacy)) {
-                $page->requires->yui_module('moodle-block_community-imagegallery',
-                        'M.blocks_community.init_imagegallery',
-                        array(array('imageids' => array($hubcourseid),
-                                'imagenumbers' => array($screenshotsnumber),
-                                'huburl' => $huburl)));
-            }
-        } else {
-            $defaultfullname = $course->fullname;
-            $defaultshortname = $course->shortname;
-            $defaultsummary = clean_param($course->summary, PARAM_TEXT);
-            if (empty($course->lang)) {
-                $language = get_site()->lang;
-                if (empty($language)) {
-                    $defaultlanguage = current_language();
-                } else {
-                    $defaultlanguage = $language;
-                }
-            } else {
-                $defaultlanguage = $course->lang;
-            }
-            $defaultpublishername = $USER->firstname . ' ' . $USER->lastname;
-            $defaultpublisheremail = $USER->email;
-            $defaultcontributornames = '';
-            $defaultcoverage = '';
-            $defaultcreatorname = $USER->firstname . ' ' . $USER->lastname;
-            $defaultlicenceshortname = 'cc';
-            $defaultsubject = 'none';
-            $defaultaudience = HUB_AUDIENCE_STUDENTS;
-            $defaulteducationallevel = HUB_EDULEVEL_TERTIARY;
-            $defaultcreatornotes = '';
-            $defaultcreatornotesformat = FORMAT_HTML;
-            $screenshotsnumber = 0;
-        }
-
-        //the input parameters
-        $mform->addElement('header', 'moodle', get_string('publicationinfo', 'hub'));
-
-        $mform->addElement('text', 'name', get_string('coursename', 'hub'),
-                array('class' => 'metadatatext'));
-        $mform->addRule('name', $strrequired, 'required', null, 'client');
-        $mform->setType('name', PARAM_TEXT);
-        $mform->setDefault('name', $defaultfullname);
-        $mform->addHelpButton('name', 'name', 'hub');
-
-        $mform->addElement('hidden', 'id', $this->_customdata['id']);
-        $mform->setType('id', PARAM_INT);
-
-        if ($share) {
-            $buttonlabel = get_string('shareon', 'hub', !empty($hubname) ? $hubname : $huburl);
-
-            $mform->addElement('hidden', 'share', $share);
-            $mform->setType('share', PARAM_BOOL);
-            $mform->addElement('text', 'demourl', get_string('demourl', 'hub'),
-                    array('class' => 'metadatatext'));
-            $mform->setType('demourl', PARAM_URL);
-            $mform->setDefault('demourl', new moodle_url("/course/view.php?id=" . $course->id));
-            $mform->addHelpButton('demourl', 'demourl', 'hub');
-        }
-
-        if ($advertise) {
-            if (empty($publishedcourses)) {
-                $buttonlabel = get_string('advertiseon', 'hub', !empty($hubname) ? $hubname : $huburl);
-            } else {
-                $buttonlabel = get_string('readvertiseon', 'hub', !empty($hubname) ? $hubname : $huburl);
-            }
-            $mform->addElement('hidden', 'advertise', $advertise);
-            $mform->setType('advertise', PARAM_BOOL);
-            $mform->addElement('hidden', 'courseurl', $CFG->wwwroot . "/course/view.php?id=" . $course->id);
-            $mform->setType('courseurl', PARAM_URL);
-            $mform->addElement('static', 'courseurlstring', get_string('courseurl', 'hub'));
-            $mform->setDefault('courseurlstring', new moodle_url("/course/view.php?id=" . $course->id));
-            $mform->addHelpButton('courseurlstring', 'courseurl', 'hub');
-        }
-
-        $mform->addElement('text', 'courseshortname', get_string('courseshortname', 'hub'),
-                array('class' => 'metadatatext'));
-        $mform->setDefault('courseshortname', $defaultshortname);
-        $mform->addHelpButton('courseshortname', 'courseshortname', 'hub');
-        $mform->setType('courseshortname', PARAM_TEXT);
-        $mform->addElement('textarea', 'description', get_string('description'), array('rows' => 10,
-            'cols' => 57));
-        $mform->addRule('description', $strrequired, 'required', null, 'client');
-        $mform->setDefault('description', $defaultsummary);
-        $mform->setType('description', PARAM_TEXT);
-        $mform->addHelpButton('description', 'description', 'hub');
-
-        $languages = get_string_manager()->get_list_of_languages();
-        core_collator::asort($languages);
-        $mform->addElement('select', 'language', get_string('language'), $languages);
-        $mform->setDefault('language', $defaultlanguage);
-        $mform->addHelpButton('language', 'language', 'hub');
-
-
-        $mform->addElement('text', 'publishername', get_string('publishername', 'hub'),
-                array('class' => 'metadatatext'));
-        $mform->setDefault('publishername', $defaultpublishername);
-        $mform->addRule('publishername', $strrequired, 'required', null, 'client');
-        $mform->addHelpButton('publishername', 'publishername', 'hub');
-        $mform->setType('publishername', PARAM_NOTAGS);
-
-        $mform->addElement('text', 'publisheremail', get_string('publisheremail', 'hub'),
-                array('class' => 'metadatatext'));
-        $mform->setDefault('publisheremail', $defaultpublisheremail);
-        $mform->addRule('publisheremail', $strrequired, 'required', null, 'client');
-        $mform->addHelpButton('publisheremail', 'publisheremail', 'hub');
-        $mform->setType('publisheremail', PARAM_EMAIL);
-
-        $mform->addElement('text', 'creatorname', get_string('creatorname', 'hub'),
-                array('class' => 'metadatatext'));
-        $mform->addRule('creatorname', $strrequired, 'required', null, 'client');
-        $mform->setType('creatorname', PARAM_NOTAGS);
-        $mform->setDefault('creatorname', $defaultcreatorname);
-        $mform->addHelpButton('creatorname', 'creatorname', 'hub');
-
-        $mform->addElement('text', 'contributornames', get_string('contributornames', 'hub'),
-                array('class' => 'metadatatext'));
-        $mform->setDefault('contributornames', $defaultcontributornames);
-        $mform->addHelpButton('contributornames', 'contributornames', 'hub');
-        $mform->setType('contributornames', PARAM_NOTAGS);
-
-        $mform->addElement('text', 'coverage', get_string('tags', 'hub'),
-                array('class' => 'metadatatext'));
-        $mform->setType('coverage', PARAM_TEXT);
-        $mform->setDefault('coverage', $defaultcoverage);
-        $mform->addHelpButton('coverage', 'tags', 'hub');
-
-
-
-        require_once($CFG->libdir . "/licenselib.php");
-        $licensemanager = new license_manager();
-        $licences = $licensemanager->get_licenses();
-        $options = array();
-        foreach ($licences as $license) {
-            $options[$license->shortname] = get_string($license->shortname, 'license');
-        }
-        $mform->addElement('select', 'licence', get_string('license'), $options);
-        $mform->setDefault('licence', $defaultlicenceshortname);
-        unset($options);
-        $mform->addHelpButton('licence', 'licence', 'hub');
-
-        $options = $publicationmanager->get_sorted_subjects();
-
-        $mform->addElement('searchableselector', 'subject',
-            get_string('subject', 'hub'), $options);
-        unset($options);
-        $mform->addHelpButton('subject', 'subject', 'hub');
-        $mform->setDefault('subject', $defaultsubject);
-        $mform->addRule('subject', $strrequired, 'required', null, 'client');
-
-        $options = array();
-        $options[HUB_AUDIENCE_EDUCATORS] = get_string('audienceeducators', 'hub');
-        $options[HUB_AUDIENCE_STUDENTS] = get_string('audiencestudents', 'hub');
-        $options[HUB_AUDIENCE_ADMINS] = get_string('audienceadmins', 'hub');
-        $mform->addElement('select', 'audience', get_string('audience', 'hub'), $options);
-        $mform->setDefault('audience', $defaultaudience);
-        unset($options);
-        $mform->addHelpButton('audience', 'audience', 'hub');
-
-        $options = array();
-        $options[HUB_EDULEVEL_PRIMARY] = get_string('edulevelprimary', 'hub');
-        $options[HUB_EDULEVEL_SECONDARY] = get_string('edulevelsecondary', 'hub');
-        $options[HUB_EDULEVEL_TERTIARY] = get_string('eduleveltertiary', 'hub');
-        $options[HUB_EDULEVEL_GOVERNMENT] = get_string('edulevelgovernment', 'hub');
-        $options[HUB_EDULEVEL_ASSOCIATION] = get_string('edulevelassociation', 'hub');
-        $options[HUB_EDULEVEL_CORPORATE] = get_string('edulevelcorporate', 'hub');
-        $options[HUB_EDULEVEL_OTHER] = get_string('edulevelother', 'hub');
-        $mform->addElement('select', 'educationallevel', get_string('educationallevel', 'hub'), $options);
-        $mform->setDefault('educationallevel', $defaulteducationallevel);
-        unset($options);
-        $mform->addHelpButton('educationallevel', 'educationallevel', 'hub');
-
-        $editoroptions = array('maxfiles' => 0, 'maxbytes' => 0, 'trusttext' => false, 'forcehttps' => false);
-        $mform->addElement('editor', 'creatornotes', get_string('creatornotes', 'hub'), '', $editoroptions);
-        $mform->addRule('creatornotes', $strrequired, 'required', null, 'client');
-        $mform->setType('creatornotes', PARAM_CLEANHTML);
-        $mform->addHelpButton('creatornotes', 'creatornotes', 'hub');
-
-        if ($advertise) {
-            if (!empty($screenshotsnumber)) {
-
-                if (!empty($privacy)) {
-                    $baseurl = new moodle_url($huburl . '/local/hub/webservice/download.php',
-                                    array('courseid' => $hubcourseid, 'filetype' => HUB_SCREENSHOT_FILE_TYPE));
-                    $screenshothtml = html_writer::empty_tag('img',
-                                    array('src' => $baseurl, 'alt' => $defaultfullname));
-                    $screenshothtml = html_writer::tag('div', $screenshothtml,
-                                    array('class' => 'coursescreenshot',
-                                        'id' => 'image-' . $hubcourseid));
-                } else {
-                    $screenshothtml = get_string('existingscreenshotnumber', 'hub', $screenshotsnumber);
-                }
-                $mform->addElement('static', 'existingscreenshots', get_string('existingscreenshots', 'hub'), $screenshothtml);
-                $mform->addHelpButton('existingscreenshots', 'deletescreenshots', 'hub');
-                $mform->addElement('checkbox', 'deletescreenshots', '', ' ' . get_string('deletescreenshots', 'hub'));
-            }
-
-            $mform->addElement('hidden', 'existingscreenshotnumber', $screenshotsnumber);
-            $mform->setType('existingscreenshotnumber', PARAM_INT);
-        }
-
-        $mform->addElement('filemanager', 'screenshots', get_string('addscreenshots', 'hub'), null,
-                array('subdirs' => 0,
-                    'maxbytes' => 1000000,
-                    'maxfiles' => 3
-        ));
-        $mform->addHelpButton('screenshots', 'screenshots', 'hub');
-
-        $this->add_action_buttons(false, $buttonlabel);
-
-        //set default value for creatornotes editor
-        $data = new stdClass();
-        $data->creatornotes = array();
-        $data->creatornotes['text'] = $defaultcreatornotes;
-        $data->creatornotes['format'] = $defaultcreatornotesformat;
-        $this->set_data($data);
-    }
-
-    function validation($data, $files) {
-        global $CFG;
-
-        $errors = array();
-
-        if ($this->_form->_submitValues['subject'] == 'none') {
-            $errors['subject'] = get_string('mustselectsubject', 'hub');
-        }
-
-        return $errors;
-    }
-
-}
-
+debugging('Support for alternative hubs has been removed from Moodle in 3.4. For communication with moodle.net ' .
+    'see lib/classes/moodlenet/ .', DEBUG_DEVELOPER);
index af0d596..72330f6 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 //
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-/// TIME PERIOD ///
-
-define('HUB_LASTMODIFIED_WEEK', 7);
-
-define('HUB_LASTMODIFIED_FORTEENNIGHT', 14);
-
-define('HUB_LASTMODIFIED_MONTH', 30);
-
-
-
-//// AUDIENCE ////
-
-/**
- * Audience: educators
- */
-define('HUB_AUDIENCE_EDUCATORS', 'educators');
-
-/**
- * Audience: students
- */
-define('HUB_AUDIENCE_STUDENTS', 'students');
-
-/**
- * Audience: admins
- */
-define('HUB_AUDIENCE_ADMINS', 'admins');
-
-
-
-///// EDUCATIONAL LEVEL /////
-
-/**
- * Educational level: primary
- */
-define('HUB_EDULEVEL_PRIMARY', 'primary');
-
-/**
- * Educational level: secondary
- */
-define('HUB_EDULEVEL_SECONDARY', 'secondary');
-
-/**
- * Educational level: tertiary
- */
-define('HUB_EDULEVEL_TERTIARY', 'tertiary');
-
-/**
- * Educational level: government
- */
-define('HUB_EDULEVEL_GOVERNMENT', 'government');
-
-/**
- * Educational level: association
- */
-define('HUB_EDULEVEL_ASSOCIATION', 'association');
-
-/**
- * Educational level: corporate
- */
-define('HUB_EDULEVEL_CORPORATE', 'corporate');
-
-/**
- * Educational level: other
- */
-define('HUB_EDULEVEL_OTHER', 'other');
-
-
-
-///// FILE TYPES /////
-
-/**
- * FILE TYPE: COURSE SCREENSHOT
- */
-define('HUB_SCREENSHOT_FILE_TYPE', 'screenshot');
-
-/**
- * FILE TYPE: HUB SCREENSHOT
- */
-define('HUB_HUBSCREENSHOT_FILE_TYPE', 'hubscreenshot');
-
-/**
- * FILE TYPE: BACKUP
- */
-define('HUB_BACKUP_FILE_TYPE', 'backup');
-
-/**
- *
- * Course publication library
- *
- * @package   course
- * @copyright 2010 Moodle Pty Ltd (http://moodle.com)
- * @author    Jerome Mouneyrac
- * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class course_publish_manager {
-
-    /**
-     * Record a course publication
-     * @param int $hubid the hub id from the 'registered on hub' table
-     * @param int $courseid the course id from site point of view
-     * @param int $enrollable if the course is enrollable = 1, if downloadable = 0
-     * @param int $hubcourseid the course id from the hub point of view
-     */
-    public function add_course_publication($huburl, $courseid, $enrollable, $hubcourseid) {
-        global $DB;
-        $publication = new stdClass();
-        $publication->huburl = $huburl;
-        $publication->courseid = $courseid;
-        $publication->hubcourseid = $hubcourseid;
-        $publication->enrollable = (int) $enrollable;
-        $publication->timepublished = time();
-        $DB->insert_record('course_published', $publication);
-    }
-
-    /**
-     * Update a enrollable course publication
-     * @param int $publicationid
-     */
-    public function update_enrollable_course_publication($publicationid) {
-        global $DB;
-        $publication = new stdClass();
-        $publication->id = $publicationid;
-        $publication->timepublished = time();
-        $DB->update_record('course_published', $publication);
-    }
-
-    /**
-     * Update a course publication
-     * @param object $publication
-     */
-    public function update_publication($publication) {
-        global $DB;
-        $DB->update_record('course_published', $publication);
-    }
-
-    /**
-     * Get courses publications
-     * @param int $hubid specify a hub
-     * @param int $courseid specify a course
-     * @param int $enrollable specify type of publication (enrollable or downloadable)
-     * @return array of publications
-     */
-    public function get_publications($huburl = null, $courseid = null, $enrollable = -1) {
-        global $DB;
-        $params = array();
-
-        if (!empty($huburl)) {
-            $params['huburl'] = $huburl;
-        }
-
-        if (!empty($courseid)) {
-            $params['courseid'] = $courseid;
-        }
-
-        if ($enrollable != -1) {
-            $params['enrollable'] = (int) $enrollable;
-        }
-
-        return $DB->get_records('course_published', $params);
-    }
-
-    /**
-     * Get a publication for a course id on a hub
-     * (which is either the id of the unique possible enrollable publication of a course,
-     * either an id of one of the downloadable publication)
-     * @param int $hubcourseid
-     * @param string $huburl
-     * @return object publication
-     */
-    public function get_publication($hubcourseid, $huburl) {
-        global $DB;
-        return $DB->get_record('course_published',
-                array('hubcourseid' => $hubcourseid, 'huburl' => $huburl));
-    }
-
-    /**
-     * Get all publication for a course
-     * @param int $courseid
-     * @return array of publication
-     */
-    public 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
-                ORDER BY cp.enrollable DESC, rh.hubname, cp.timepublished';
-        $params = array('courseid' => $courseid);
-        return $DB->get_records_sql($sql, $params);
-    }
-
-    /**
-     * Get the hub concerned by a publication
-     * @param int $publicationid
-     * @return object the hub (id, name, url, token)
-     */
-    public function get_registeredhub_by_publication($publicationid) {
-        global $DB;
-        $sql = 'SELECT rh.huburl, rh.hubname, rh.token
-                FROM {course_published} cp, {registration_hubs} rh
-                WHERE cp.huburl = rh.huburl and cp.id = :publicationid';
-        $params = array('publicationid' => $publicationid);
-        return $DB->get_record_sql($sql, $params);
-    }
-
-    /**
-     * Delete a publication
-     * @param int $publicationid
-     */
-    public function delete_publication($publicationid) {
-        global $DB;
-        $DB->delete_records('course_published', array('id' => $publicationid));
-    }
-
-    /**
-     * Delete publications for a hub
-     * @param string $huburl
-     * @param int $enrollable
-     */
-    public function delete_hub_publications($huburl, $enrollable = -1) {
-        global $DB;
-
-        $params = array();
-
-        if (!empty($huburl)) {
-            $params['huburl'] = $huburl;
-        }
-
-        if ($enrollable != -1) {
-            $params['enrollable'] = (int) $enrollable;
-        }
-
-        $DB->delete_records('course_published', $params);
-    }
-
-    /**
-     * Get an array of all block instances for a given context
-     * @param int $contextid a context id
-     * @return array of block instances.
-     */
-    public function get_block_instances_by_context($contextid, $sort = '') {
-        global $DB;
-        return $DB->get_records('block_instances', array('parentcontextid' => $contextid), $sort);
-    }
-
-    /**
-     * Retrieve all the sorted course subjects
-     * @return array $subjects
-     */
-    public 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;
-    }
-
-}
 
+defined('MOODLE_INTERNAL') || die();
index e179229..199991f 100644 (file)
@@ -90,6 +90,7 @@ $string['emailalert'] = 'Email notifications';
 $string['emailalert_help'] = 'If this is enabled the hub administrator will send you emails about security issues and other important news.';
 $string['enrollable'] = 'Enrollable';
 $string['errorbadimageheightwidth'] = 'The image should have a maximum size of {$a->width} X {$a->height}';
+$string['errorconnect'] = 'Connection error: {$a}';
 $string['errorcourseinfo'] = 'An error occurred when retrieving course metadata from the hub ({$a}). Please try again to retrieve the course metadata from the hub by reloading this page later. Otherwise you can decide to continue the registration process with the following default metadata. ';
 $string['errorcoursepublish'] = 'An error occurred during the course publication ({$a}). Please try again later.';
 $string['errorcoursewronglypublished'] = 'A publication error has been returned by the hub. Please try again later.';
@@ -97,9 +98,12 @@ $string['errorcron'] = 'An error occurred during registration update on "{$a->hu
 $string['errorcronnoxmlrpc'] = 'XML-RPC must be enabled in order to update the registration.';
 $string['errorhublisting'] = 'An error occurred when retrieving the hub listing from Moodle. Please try again later. ({$a})';
 $string['errorlangnotrecognized'] = 'The provided language code is unknown by Moodle. Please contact {$a}';
+$string['errorotherhubsnotsupported'] = 'This page can no longer be used for registration with sites other than Moodle.net';
 $string['errorregistration'] = 'An error occurred during registration, please try again later. ({$a})';
 $string['errorunpublishcourses'] = 'Due to an unexpected error, the courses could not be deleted on the hub. Try again later (recommended) or contact the hub administrator.';
+$string['errorws'] = '{$a}';
 $string['existingscreenshotnumber'] = '{$a} existing screenshots. You will be able to see these screenshots on this page, only once the hub administrator enables your course.';
+$string['errorregistrationupdate'] = 'An error occurred during registration update ({$a})';
 $string['existingscreenshots'] = 'Existing screenshots';
 $string['forceunregister'] = 'Yes, clean registration data';
 $string['forceunregisterconfirmation'] = 'Your site cannot reach {$a}. This hub could be temporarily down. Unless you are sure you want to continue to remove registration locally, please cancel and try again later.';
diff --git a/lib/classes/hub/api.php b/lib/classes/hub/api.php
new file mode 100644 (file)
index 0000000..fe6e112
--- /dev/null
@@ -0,0 +1,433 @@
+<?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 communication
+ *
+ * @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 webservice_xmlrpc_client;
+use moodle_exception;
+use curl;
+use stdClass;
+use coding_exception;
+use moodle_url;
+
+/**
+ * Methods to communicate with moodle.net web services
+ *
+ * @package    core
+ * @copyright  2017 Marina Glancy
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class api {
+
+    /** @var File type: Course screenshot */
+    const HUB_SCREENSHOT_FILE_TYPE = 'screenshot';
+
+    /** @var File type: Hub screenshot */
+    const HUB_HUBSCREENSHOT_FILE_TYPE = 'hubscreenshot';
+
+    /** @var File type: Backup */
+    const HUB_BACKUP_FILE_TYPE = 'backup';
+
+    /**
+     * Calls moodle.net WS
+     *
+     * @param string $function name of WS function
+     * @param array $data parameters of WS function
+     * @param bool $allowpublic allow request without moodle.net registration
+     * @return mixed depends on the function
+     * @throws moodle_exception
+     */
+    protected static function call($function, array $data = [], $allowpublic = false) {
+
+        $token = registration::get_token() ?: 'publichub';
+        if (!$allowpublic && $token === 'publichub') {
+            // This will throw an exception.
+            registration::require_registration();
+        }
+
+        if (extension_loaded('xmlrpc')) {
+            // Use XMLRPC protocol.
+            return self::call_xmlrpc($token, $function, $data);
+        } else {
+            // Use REST.
+            return self::call_rest($token, $function, $data);
+        }
+    }
+
+    /**
+     * Performs REST request to moodle.net (using GET method)
+     *
+     * @param string $token
+     * @param string $function
+     * @param array $data
+     * @return mixed
+     * @throws moodle_exception
+     */
+    protected static function call_xmlrpc($token, $function, array $data) {
+        global $CFG;
+        require_once($CFG->dirroot . "/webservice/xmlrpc/lib.php");
+
+        $serverurl = HUB_MOODLEORGHUBURL . "/local/hub/webservice/webservices.php";
+        $xmlrpcclient = new webservice_xmlrpc_client($serverurl, $token);
+        try {
+            return $xmlrpcclient->call($function, $data);
+        } catch (\Exception $e) {
+            // Function webservice_xmlrpc_client::call() can throw Exception, wrap it into moodle_exception.
+            throw new moodle_exception('errorws', 'hub', '', $e->getMessage());
+        }
+    }
+
+    /**
+     * Performs REST request to moodle.net (using GET method)
+     *
+     * @param string $token
+     * @param string $function
+     * @param array $data
+     * @return mixed
+     * @throws moodle_exception
+     */
+    protected static function call_rest($token, $function, array $data) {
+        $params = [
+                'wstoken' => $token,
+                'wsfunction' => $function,
+                'moodlewsrestformat' => 'json'
+            ] + $data;
+
+        $curl = new curl();
+        $serverurl = HUB_MOODLEORGHUBURL . "/local/hub/webservice/webservices.php";
+        $curloutput = @json_decode($curl->get($serverurl, $params), true);
+        $info = $curl->get_info();
+        if ($curl->get_errno()) {
+            throw new moodle_exception('errorconnect', 'hub', '', $curl->error);
+        } else if (isset($curloutput['exception'])) {
+            // Error message returned by web service.
+            throw new moodle_exception('errorws', 'hub', '', $curloutput['message']);
+        } else if ($info['http_code'] != 200) {
+            throw new moodle_exception('errorconnect', 'hub', '', $info['http_code']);
+        } else {
+            return $curloutput;
+        }
+    }
+
+    /**
+     * Update site registration on moodle.net
+     *
+     * @param array $siteinfo
+     * @throws moodle_exception
+     */
+    public static function update_registration(array $siteinfo) {
+        $params = array('siteinfo' => $siteinfo);
+        self::call('hub_update_site_info', $params);
+    }
+
+    /**
+     * Returns information about moodle.net
+     *
+     * Example of the return array:
+     * {
+     *     "courses": 384,
+     *     "description": "Moodle.net connects you with free content and courses shared by Moodle ...",
+     *     "downloadablecourses": 190,
+     *     "enrollablecourses": 194,
+     *     "hublogo": 1,
+     *     "language": "en",
+     *     "name": "Moodle.net",
+     *     "sites": 274175,
+     *     "url": "https://moodle.net",
+     *     "imgurl": "https://moodle.net/local/hub/webservice/download.php?filetype=hubscreenshot"
+     * }
+     *
+     * @return array
+     * @throws moodle_exception
+     */
+    public static function get_hub_info() {
+        $info = self::call('hub_get_info', [], true);
+        $info['imgurl'] = new moodle_url(HUB_MOODLEORGHUBURL . '/local/hub/webservice/download.php',
+            ['filetype' => self::HUB_HUBSCREENSHOT_FILE_TYPE]);
+        return $info;
+    }
+
+    /**
+     * Calls WS function hub_get_courses
+     *
+     * Parameter $options may have any of these fields:
+     * [
+     *     'ids' => new external_multiple_structure(new external_value(PARAM_INTEGER, 'id of a course in the hub course
+     *          directory'), 'ids of course', VALUE_OPTIONAL),
+     *     'sitecourseids' => new external_multiple_structure(new external_value(PARAM_INTEGER, 'id of a course in the
+     *          site'), 'ids of course in the site', VALUE_OPTIONAL),
+     *     'coverage' => new external_value(PARAM_TEXT, 'coverage', VALUE_OPTIONAL),
+     *     'licenceshortname' => new external_value(PARAM_ALPHANUMEXT, 'licence short name', VALUE_OPTIONAL),
+     *     'subject' => new external_value(PARAM_ALPHANUM, 'subject', VALUE_OPTIONAL),
+     *     'audience' => new external_value(PARAM_ALPHA, 'audience', VALUE_OPTIONAL),
+     *     'educationallevel' => new external_value(PARAM_ALPHA, 'educational level', VALUE_OPTIONAL),
+     *     'language' => new external_value(PARAM_ALPHANUMEXT, 'language', VALUE_OPTIONAL),
+     *     'orderby' => new external_value(PARAM_ALPHA, 'orderby method: newest, eldest, publisher, fullname,
+     *          ratingaverage', VALUE_OPTIONAL),
+     *     'givememore' => new external_value(PARAM_INT, 'next range of result - range size being set by the hub
+     *          server ', VALUE_OPTIONAL),
+     *     'allsitecourses' => new external_value(PARAM_INTEGER,
+     *          'if 1 return all not visible and visible courses whose siteid is the site
+     *          matching token. Only courses of this site are returned.
+     *          givememore parameter is ignored if this param = 1.
+     *          In case of public token access, this param option is ignored', VALUE_DEFAULT, 0),
+     * ]
+     *
+     * Each course in the returned array of courses will have fields:
+     * [
+     *     'id' => new external_value(PARAM_INTEGER, 'id'),
+     *     'fullname' => new external_value(PARAM_TEXT, 'course name'),
+     *     'shortname' => new external_value(PARAM_TEXT, 'course short name'),
+     *     'description' => new external_value(PARAM_TEXT, 'course description'),
+     *     'language' => new external_value(PARAM_ALPHANUMEXT, 'course language'),
+     *     'publishername' => new external_value(PARAM_TEXT, 'publisher name'),
+     *     'publisheremail' => new external_value(PARAM_EMAIL, 'publisher email', VALUE_OPTIONAL),
+     *     'privacy' => new external_value(PARAM_INT, 'privacy: published or not', VALUE_OPTIONAL),
+     *     'sitecourseid' => new external_value(PARAM_INT, 'course id on the site', VALUE_OPTIONAL),
+     *     'contributornames' => new external_value(PARAM_TEXT, 'contributor names', VALUE_OPTIONAL),
+     *     'coverage' => new external_value(PARAM_TEXT, 'coverage', VALUE_OPTIONAL),
+     *     'creatorname' => new external_value(PARAM_TEXT, 'creator name'),
+     *     'licenceshortname' => new external_value(PARAM_ALPHANUMEXT, 'licence short name'),
+     *     'subject' => new external_value(PARAM_ALPHANUM, 'subject'),
+     *     'audience' => new external_value(PARAM_ALPHA, 'audience'),
+     *     'educationallevel' => new external_value(PARAM_ALPHA, 'educational level'),
+     *     'creatornotes' => new external_value(PARAM_RAW, 'creator notes'),
+     *     'creatornotesformat' => new external_value(PARAM_INTEGER, 'notes format'),
+     *     'demourl' => new external_value(PARAM_URL, 'demo URL', VALUE_OPTIONAL),
+     *     'courseurl' => new external_value(PARAM_URL, 'course URL', VALUE_OPTIONAL),
+     *     'backupsize' => new external_value(PARAM_INT, 'course backup size in bytes', VALUE_OPTIONAL),
+     *     'enrollable' => new external_value(PARAM_BOOL, 'is the course enrollable'),
+     *     'screenshots' => new external_value(PARAM_INT, 'total number of screenshots'),
+     *     'timemodified' => new external_value(PARAM_INT, 'time of last modification - timestamp'),
+     *     'contents' => new external_multiple_structure(new external_single_structure(
+     *         array(
+     *             'moduletype' => new external_value(PARAM_ALPHA, 'the type of module (activity/block)'),
+     *             'modulename' => new external_value(PARAM_TEXT, 'the name of the module (forum, resource etc)'),
+     *             'contentcount' => new external_value(PARAM_INT, 'how many time the module is used in the course'),
+     *         )), 'contents', VALUE_OPTIONAL),
+     *     'rating' => new external_single_structure (
+     *         array(
+     *              'aggregate' =>  new external_value(PARAM_FLOAT, 'Rating average', VALUE_OPTIONAL),
+     *              'scaleid' => new external_value(PARAM_INT, 'Rating scale'),
+     *              'count' => new external_value(PARAM_INT, 'Rating count'),
+     *         ), 'rating', VALUE_OPTIONAL),
+     *     'comments' => new external_multiple_structure(new external_single_structure (
+     *          array(
+     *              'comment' => new external_value(PARAM_TEXT, 'the comment'),
+     *              'commentator' => new external_value(PARAM_TEXT, 'the name of commentator'),
+     *              'date' => new external_value(PARAM_INT, 'date of the comment'),
+     *         )), 'contents', VALUE_OPTIONAL),
+     *     'outcomes' => new external_multiple_structure(new external_single_structure(
+     *          array(
+     *              'fullname' => new external_value(PARAM_TEXT, 'the outcome fullname')
+     *          )), 'outcomes', VALUE_OPTIONAL)
+     * ]
+     *
+     * Additional fields for each course:
+     *      'screenshotbaseurl' (moodle_url) URL of the first screenshot, only set if $course['screenshots']>0
+     *      'commenturl' (moodle_url) URL for comments
+     *
+     * @param string $search search string
+     * @param bool $downloadable return downloadable courses
+     * @param bool $enrollable 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]
+     * @throws \coding_exception
+     * @throws moodle_exception
+     */
+    public static function get_courses($search, $downloadable, $enrollable, $options) {
+        static $availableoptions = ['ids', 'sitecourseids', 'coverage', 'licenceshortname', 'subject', 'audience',
+            'educationallevel', 'language', 'orderby', 'givememore', 'allsitecourses'];
+
+        if (empty($options)) {
+            $options = [];
+        } else if (is_object($options)) {
+            $options = (array)$options;
+        } else if (!is_array($options)) {
+            throw new \coding_exception('Parameter $options is invalid');
+        }
+
+        if ($unknownkeys = array_diff(array_keys($options), $availableoptions)) {
+            throw new \coding_exception('Unknown option(s): ' . join(', ', $unknownkeys));
+        }
+
+        $params = [
+            'search' => $search,
+            'downloadable' => (int)(bool)$downloadable,
+            'enrollable' => (int)(bool)$enrollable,
+            'options' => $options
+        ];
+        $result = self::call('hub_get_courses', $params, true);
+        $courses = $result['courses'];
+        $coursetotal = $result['coursetotal'];
+
+        foreach ($courses as $idx => $course) {
+            $courses[$idx]['screenshotbaseurl'] = null;
+            if (!empty($course['screenshots'])) {
+                $courses[$idx]['screenshotbaseurl'] = new moodle_url(HUB_MOODLEORGHUBURL . '/local/hub/webservice/download.php',
+                    array('courseid' => $course['id'],
+                        'filetype' => self::HUB_SCREENSHOT_FILE_TYPE));
+            }
+            $courses[$idx]['commenturl'] = new moodle_url(HUB_MOODLEORGHUBURL,
+                array('courseid' => $course['id'], 'mustbelogged' => true));
+        }
+
+        return [$courses, $coursetotal];
+    }
+
+    /**
+     * Unregister the site
+     *
+     * @throws moodle_exception
+     */
+    public static function unregister_site() {
+        self::call('hub_unregister_site');
+    }
+
+    /**
+     * Unpublish courses
+     *
+     * @param int[]|int $courseids
+     * @throws moodle_exception
+     */
+    public static function unregister_courses($courseids) {
+        $courseids = (array)$courseids;
+        $params = array('courseids' => $courseids);
+        self::call('hub_unregister_courses', $params);
+    }
+
+    /**
+     * Publish one course
+     *
+     * Expected contents of $courseinfo:
+     * [
+     *     'sitecourseid' => new external_value(PARAM_INT, 'the id of the course on the publishing site'),
+     *     'fullname' => new external_value(PARAM_TEXT, 'course name'),
+     *     'shortname' => new external_value(PARAM_TEXT, 'course short name'),
+     *     'description' => new external_value(PARAM_TEXT, 'course description'),
+     *     'language' => new external_value(PARAM_ALPHANUMEXT, 'course language'),
+     *     'publishername' => new external_value(PARAM_TEXT, 'publisher name'),
+     *     'publisheremail' => new external_value(PARAM_EMAIL, 'publisher email'),
+     *     'contributornames' => new external_value(PARAM_TEXT, 'contributor names'),
+     *     'coverage' => new external_value(PARAM_TEXT, 'coverage'),
+     *     'creatorname' => new external_value(PARAM_TEXT, 'creator name'),
+     *     'licenceshortname' => new external_value(PARAM_ALPHANUMEXT, 'licence short name'),
+     *     'subject' => new external_value(PARAM_ALPHANUM, 'subject'),
+     *     'audience' => new external_value(PARAM_ALPHA, 'audience'),
+     *     'educationallevel' => new external_value(PARAM_ALPHA, 'educational level'),
+     *     'creatornotes' => new external_value(PARAM_RAW, 'creator notes'),
+     *     'creatornotesformat' => new external_value(PARAM_INTEGER, 'notes format'),
+     *     'demourl' => new external_value(PARAM_URL, 'demo URL', VALUE_OPTIONAL),
+     *     'courseurl' => new external_value(PARAM_URL, 'course URL', VALUE_OPTIONAL),
+     *     'enrollable' => new external_value(PARAM_BOOL, 'is the course enrollable', VALUE_DEFAULT, 0),
+     *     'screenshots' => new external_value(PARAM_INT, 'the number of screenhots', VALUE_OPTIONAL),
+     *     'deletescreenshots' => new external_value(PARAM_INT, 'ask to delete all the existing screenshot files
+     *          (it does not reset the screenshot number)', VALUE_DEFAULT, 0),
+     *     'contents' => new external_multiple_structure(new external_single_structure(
+     *          array(
+     *              'moduletype' => new external_value(PARAM_ALPHA, 'the type of module (activity/block)'),
+     *              'modulename' => new external_value(PARAM_TEXT, 'the name of the module (forum, resource etc)'),
+     *              'contentcount' => new external_value(PARAM_INT, 'how many time the module is used in the course'),
+     *          )), 'contents', VALUE_OPTIONAL),
+     *     'outcomes' => new external_multiple_structure(new external_single_structure(
+     *         array(
+     *              'fullname' => new external_value(PARAM_TEXT, 'the outcome fullname')
+     *          )), 'outcomes', VALUE_OPTIONAL)
+     * ]
+     *
+     * @param array|\stdClass $courseinfo
+     * @return int id of the published course on the hub
+     * @throws moodle_exception if communication to moodle.net failed or course could not be published
+     */
+    public static function register_course($courseinfo) {
+        $params = array('courses' => array($courseinfo));
+        $hubcourseids = self::call('hub_register_courses', $params);
+        if (count($hubcourseids) != 1) {
+            throw new moodle_exception('errorcoursewronglypublished', 'hub');
+        }
+        return $hubcourseids[0];
+    }
+
+    /**
+     * Uploads a screenshot for the published course
+     *
+     * @param int $hubcourseid id of the published course on moodle.net, it must be published from this site
+     * @param \stored_file $file
+     * @param int $screenshotnumber ordinal number of the screenshot
+     */
+    public static function add_screenshot($hubcourseid, \stored_file $file, $screenshotnumber) {
+        $curl = new \curl();
+        $params = array();
+        $params['filetype'] = self::HUB_SCREENSHOT_FILE_TYPE;
+        $params['file'] = $file;
+        $params['courseid'] = $hubcourseid;
+        $params['filename'] = $file->get_filename();
+        $params['screenshotnumber'] = $screenshotnumber;
+        $params['token'] = registration::get_token(MUST_EXIST);
+        $curl->post(HUB_MOODLEORGHUBURL . "/local/hub/webservice/upload.php", $params);
+    }
+
+    /**
+     * Downloads course backup
+     *
+     * @param int $hubcourseid id of the course on moodle.net
+     * @param string $path local path (in tempdir) to save the downloaded backup to.
+     */
+    public static function download_course_backup($hubcourseid, $path) {
+        $fp = fopen($path, 'w');
+
+        $curlurl = new \moodle_url(HUB_MOODLEORGHUBURL . '/local/hub/webservice/download.php',
+            ['filetype' => self::HUB_BACKUP_FILE_TYPE, 'courseid' => $hubcourseid]);
+
+        // Send an identification token if the site is registered.
+        if ($token = registration::get_token()) {
+            $curlurl->param('token', $token);
+        }
+
+        $ch = curl_init($curlurl->out(false));
+        curl_setopt($ch, CURLOPT_FILE, $fp);
+        curl_exec($ch);
+        curl_close($ch);
+        fclose($fp);
+    }
+
+    /**
+     * 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) {
+        $curl = new \curl();
+        $params = array();
+        $params['filetype'] = self::HUB_BACKUP_FILE_TYPE;
+        $params['courseid'] = $hubcourseid;
+        $params['file'] = $backupfile;
+        $params['token'] = registration::get_token();
+        $curl->post(HUB_MOODLEORGHUBURL . '/local/hub/webservice/upload.php', $params);
+    }
+}
\ No newline at end of file
diff --git a/lib/classes/hub/course_publication_form.php b/lib/classes/hub/course_publication_form.php
new file mode 100644 (file)
index 0000000..498f087
--- /dev/null
@@ -0,0 +1,308 @@
+<?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 course_publication_form
+ *
+ * @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 stdClass;
+use license_manager;
+use moodle_url;
+use core_collator;
+
+global $CFG;
+require_once($CFG->libdir . '/formslib.php');
+require_once($CFG->libdir . '/licenselib.php');
+
+/**
+ * The forms used for course publication
+ *
+ * @package    core
+ * @copyright  2017 Marina Glancy
+ * @author     Jerome Mouneyrac <jerome@mouneyrac.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class course_publication_form extends \moodleform {
+
+    /**
+     * Form definition
+     */
+    public function definition() {
+        global $CFG, $USER, $PAGE;
+
+        $strrequired = get_string('required');
+        $mform = & $this->_form;
+        $course = $this->_customdata['course'];
+        if (!empty($this->_customdata['publication'])) {
+            // We are editing existing publication.
+            $publication = $this->_customdata['publication'];
+            $advertise = $publication->enrollable;
+            $publishedcourse = publication::get_published_course($publication);
+        } else {
+            $publication = null;
+            $advertise = $this->_customdata['advertise'];
+        }
+        $share = !$advertise;
+
+        if (!empty($publishedcourse)) {
+            $hubcourseid = $publishedcourse['id'];
+            $defaultfullname = $publishedcourse['fullname'];
+            $defaultshortname = $publishedcourse['shortname'];
+            $defaultsummary = $publishedcourse['description'];
+            $defaultlanguage = $publishedcourse['language'];
+            $defaultpublishername = $publishedcourse['publishername'];
+            $defaultpublisheremail = $publishedcourse['publisheremail'];
+            $defaultcontributornames = $publishedcourse['contributornames'];
+            $defaultcoverage = $publishedcourse['coverage'];
+            $defaultcreatorname = $publishedcourse['creatorname'];
+            $defaultlicenceshortname = $publishedcourse['licenceshortname'];
+            $defaultsubject = $publishedcourse['subject'];
+            $defaultaudience = $publishedcourse['audience'];
+            $defaulteducationallevel = $publishedcourse['educationallevel'];
+            $defaultcreatornotes = $publishedcourse['creatornotes'];
+            $defaultcreatornotesformat = $publishedcourse['creatornotesformat'];
+            $screenshotsnumber = $publishedcourse['screenshots'];
+            $screenshotbaseurl = $publishedcourse['screenshotbaseurl'];
+            $privacy = $publishedcourse['privacy'];
+            if (($screenshotsnumber > 0) and !empty($privacy)) {
+                $PAGE->requires->yui_module('moodle-block_community-imagegallery',
+                    'M.blocks_community.init_imagegallery',
+                    array(array('imageids' => array($hubcourseid),
+                        'imagenumbers' => array($screenshotsnumber),
+                        'huburl' => HUB_MOODLEORGHUBURL)));
+            }
+        } else {
+            $defaultfullname = $course->fullname;
+            $defaultshortname = $course->shortname;
+            $defaultsummary = clean_param($course->summary, PARAM_TEXT);
+            if (empty($course->lang)) {
+                $language = get_site()->lang;
+                if (empty($language)) {
+                    $defaultlanguage = current_language();
+                } else {
+                    $defaultlanguage = $language;
+                }
+            } else {
+                $defaultlanguage = $course->lang;
+            }
+            $defaultpublishername = $USER->firstname . ' ' . $USER->lastname;
+            $defaultpublisheremail = $USER->email;
+            $defaultcontributornames = '';
+            $defaultcoverage = '';
+            $defaultcreatorname = $USER->firstname . ' ' . $USER->lastname;
+            $defaultlicenceshortname = 'cc';
+            $defaultsubject = 'none';
+            $defaultaudience = publication::HUB_AUDIENCE_STUDENTS;
+            $defaulteducationallevel = publication::HUB_EDULEVEL_TERTIARY;
+            $defaultcreatornotes = '';
+            $defaultcreatornotesformat = FORMAT_HTML;
+            $screenshotsnumber = 0;
+            $screenshotbaseurl = null;
+        }
+
+        // The input parameters.
+        $mform->addElement('header', 'moodle', get_string('publicationinfo', 'hub'));
+
+        $mform->addElement('text', 'name', get_string('coursename', 'hub'),
+            array('class' => 'metadatatext'));
+        $mform->addRule('name', $strrequired, 'required', null, 'client');
+        $mform->setType('name', PARAM_TEXT);
+        $mform->setDefault('name', $defaultfullname);
+        $mform->addHelpButton('name', 'name', 'hub');
+
+        $mform->addElement('hidden', 'id', $course->id);
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'publicationid', $publication ? $publication->id : null);
+        $mform->setType('publicationid', PARAM_INT);
+
+        if ($share) {
+            $buttonlabel = get_string('shareon', 'hub', 'Moodle.net');
+
+            $mform->addElement('hidden', 'share', $share);
+            $mform->setType('share', PARAM_BOOL);
+            $mform->addElement('text', 'demourl', get_string('demourl', 'hub'),
+                array('class' => 'metadatatext'));
+            $mform->setType('demourl', PARAM_URL);
+            $mform->setDefault('demourl', new moodle_url("/course/view.php?id=" . $course->id));
+            $mform->addHelpButton('demourl', 'demourl', 'hub');
+        }
+
+        if ($advertise) {
+            if (!$publication) {
+                $buttonlabel = get_string('advertiseon', 'hub', 'Moodle.net');
+            } else {
+                $buttonlabel = get_string('readvertiseon', 'hub', 'Moodle.net');
+            }
+            $mform->addElement('hidden', 'advertise', $advertise);
+            $mform->setType('advertise', PARAM_BOOL);
+            $mform->addElement('hidden', 'courseurl', $CFG->wwwroot . "/course/view.php?id=" . $course->id);
+            $mform->setType('courseurl', PARAM_URL);
+            $mform->addElement('static', 'courseurlstring', get_string('courseurl', 'hub'));
+            $mform->setDefault('courseurlstring', new moodle_url("/course/view.php?id=" . $course->id));
+            $mform->addHelpButton('courseurlstring', 'courseurl', 'hub');
+        }
+
+        $mform->addElement('text', 'courseshortname', get_string('courseshortname', 'hub'),
+            array('class' => 'metadatatext'));
+        $mform->setDefault('courseshortname', $defaultshortname);
+        $mform->addHelpButton('courseshortname', 'courseshortname', 'hub');
+        $mform->setType('courseshortname', PARAM_TEXT);
+        $mform->addElement('textarea', 'description', get_string('description', 'hub'), array('rows' => 10,
+            'cols' => 57));
+        $mform->addRule('description', $strrequired, 'required', null, 'client');
+        $mform->setDefault('description', $defaultsummary);
+        $mform->setType('description', PARAM_TEXT);
+        $mform->addHelpButton('description', 'description', 'hub');
+
+        $languages = get_string_manager()->get_list_of_languages();
+        core_collator::asort($languages);
+        $mform->addElement('select', 'language', get_string('language'), $languages);
+        $mform->setDefault('language', $defaultlanguage);
+        $mform->addHelpButton('language', 'language', 'hub');
+
+        $mform->addElement('text', 'publishername', get_string('publishername', 'hub'),
+            array('class' => 'metadatatext'));
+        $mform->setDefault('publishername', $defaultpublishername);
+        $mform->addRule('publishername', $strrequired, 'required', null, 'client');
+        $mform->addHelpButton('publishername', 'publishername', 'hub');
+        $mform->setType('publishername', PARAM_NOTAGS);
+
+        $mform->addElement('text', 'publisheremail', get_string('publisheremail', 'hub'),
+            array('class' => 'metadatatext'));
+        $mform->setDefault('publisheremail', $defaultpublisheremail);
+        $mform->addRule('publisheremail', $strrequired, 'required', null, 'client');
+        $mform->addHelpButton('publisheremail', 'publisheremail', 'hub');
+        $mform->setType('publisheremail', PARAM_EMAIL);
+
+        $mform->addElement('text', 'creatorname', get_string('creatorname', 'hub'),
+            array('class' => 'metadatatext'));
+        $mform->addRule('creatorname', $strrequired, 'required', null, 'client');
+        $mform->setType('creatorname', PARAM_NOTAGS);
+        $mform->setDefault('creatorname', $defaultcreatorname);
+        $mform->addHelpButton('creatorname', 'creatorname', 'hub');
+
+        $mform->addElement('text', 'contributornames', get_string('contributornames', 'hub'),
+            array('class' => 'metadatatext'));
+        $mform->setDefault('contributornames', $defaultcontributornames);
+        $mform->addHelpButton('contributornames', 'contributornames', 'hub');
+        $mform->setType('contributornames', PARAM_NOTAGS);
+
+        $mform->addElement('text', 'coverage', get_string('tags', 'hub'),
+            array('class' => 'metadatatext'));
+        $mform->setType('coverage', PARAM_TEXT);
+        $mform->setDefault('coverage', $defaultcoverage);
+        $mform->addHelpButton('coverage', 'tags', 'hub');
+
+        $licensemanager = new license_manager();
+        $licences = $licensemanager->get_licenses();
+        $options = array();
+        foreach ($licences as $license) {
+            $options[$license->shortname] = get_string($license->shortname, 'license');
+        }
+        $mform->addElement('select', 'licence', get_string('license'), $options);
+        $mform->setDefault('licence', $defaultlicenceshortname);
+        unset($options);
+        $mform->addHelpButton('licence', 'licence', 'hub');
+
+        $options = publication::get_sorted_subjects();
+
+        $mform->addElement('searchableselector', 'subject',
+            get_string('subject', 'hub'), $options);
+        unset($options);
+        $mform->addHelpButton('subject', 'subject', 'hub');
+        $mform->setDefault('subject', $defaultsubject);
+        $mform->addRule('subject', $strrequired, 'required', null, 'client');
+
+        $options = publication::audience_options();
+        $mform->addElement('select', 'audience', get_string('audience', 'hub'), $options);
+        $mform->setDefault('audience', $defaultaudience);
+        unset($options);
+        $mform->addHelpButton('audience', 'audience', 'hub');
+
+        $options = publication::educational_level_options();
+        $mform->addElement('select', 'educationallevel', get_string('educationallevel', 'hub'), $options);
+        $mform->setDefault('educationallevel', $defaulteducationallevel);
+        unset($options);
+        $mform->addHelpButton('educationallevel', 'educationallevel', 'hub');
+
+        $editoroptions = array('maxfiles' => 0, 'maxbytes' => 0, 'trusttext' => false, 'forcehttps' => false);
+        $mform->addElement('editor', 'creatornotes', get_string('creatornotes', 'hub'), '', $editoroptions);
+        $mform->addRule('creatornotes', $strrequired, 'required', null, 'client');
+        $mform->setType('creatornotes', PARAM_CLEANHTML);
+        $mform->addHelpButton('creatornotes', 'creatornotes', 'hub');
+
+        if ($advertise) {
+            if (!empty($screenshotsnumber)) {
+                if (!empty($privacy)) {
+                    $screenshothtml = \html_writer::empty_tag('img',
+                        array('src' => $screenshotbaseurl, 'alt' => $defaultfullname));
+                    $screenshothtml = \html_writer::tag('div', $screenshothtml,
+                        array('class' => 'coursescreenshot',
+                            'id' => 'image-' . $hubcourseid));
+                } else {
+                    $screenshothtml = get_string('existingscreenshotnumber', 'hub', $screenshotsnumber);
+                }
+                $mform->addElement('static', 'existingscreenshots', get_string('existingscreenshots', 'hub'), $screenshothtml);
+                $mform->addHelpButton('existingscreenshots', 'deletescreenshots', 'hub');
+                $mform->addElement('checkbox', 'deletescreenshots', '', ' ' . get_string('deletescreenshots', 'hub'));
+            }
+
+            $mform->addElement('hidden', 'existingscreenshotnumber', $screenshotsnumber);
+            $mform->setType('existingscreenshotnumber', PARAM_INT);
+        }
+
+        $mform->addElement('filemanager', 'screenshots', get_string('addscreenshots', 'hub'), null,
+            array('subdirs' => 0,
+                'maxbytes' => 1000000,
+                'maxfiles' => 3
+            ));
+        $mform->addHelpButton('screenshots', 'screenshots', 'hub');
+
+        $this->add_action_buttons(false, $buttonlabel);
+
+        // Set default value for creatornotes editor.
+        $data = new stdClass();
+        $data->creatornotes = array();
+        $data->creatornotes['text'] = $defaultcreatornotes;
+        $data->creatornotes['format'] = $defaultcreatornotesformat;
+        $this->set_data($data);
+    }
+
+    /**
+     * Custom form validation
+     *
+     * @param array $data
+     * @param array $files
+     * @return array
+     */
+    public function validation($data, $files) {
+        $errors = parent::validation($data, $files);
+
+        if ($this->_form->_submitValues['subject'] == 'none') {
+            $errors['subject'] = get_string('mustselectsubject', 'hub');
+        }
+
+        return $errors;
+    }
+}
diff --git a/lib/classes/hub/publication.php b/lib/classes/hub/publication.php
new file mode 100644 (file)
index 0000000..29c51e6
--- /dev/null
@@ -0,0 +1,409 @@
+<?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);
+    }
+}
\ No newline at end of file
diff --git a/lib/classes/hub/registration.php b/lib/classes/hub/registration.php
new file mode 100644 (file)
index 0000000..a75929e
--- /dev/null
@@ -0,0 +1,410 @@
+<?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 registration
+ *
+ * @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_system;
+use stdClass;
+
+/**
+ * Methods to use when publishing and searching courses on moodle.net
+ *
+ * @package    core
+ * @copyright  2017 Marina Glancy
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class registration {
+
+    /** @var Fields used in a site registration form */
+    const FORM_FIELDS = ['name', 'description', 'contactname', 'contactemail', 'contactphone', 'imageurl', 'privacy', 'street',
+        'regioncode', 'countrycode', 'geolocation', 'contactable', 'emailalert', 'language'];
+
+    /** @var Site privacy: not displayed */
+    const HUB_SITENOTPUBLISHED = 'notdisplayed';
+
+    /** @var Site privacy: public */
+    const HUB_SITENAMEPUBLISHED = 'named';
+
+    /** @var Site privacy: public and global */
+    const HUB_SITELINKPUBLISHED = 'linked';
+
+    /** @var stdClass cached site registration information */
+    protected static $registration = null;
+
+    /**
+     * Get site registration
+     *
+     * @param bool $confirmed
+     * @return stdClass|null
+     */
+    protected static function get_registration($confirmed = true) {
+        global $DB;
+
+        if (self::$registration === null) {
+            self::$registration = $DB->get_record('registration_hubs', ['huburl' => HUB_MOODLEORGHUBURL]);
+        }
+
+        if (self::$registration && (bool)self::$registration->confirmed == (bool)$confirmed) {
+            return self::$registration;
+        }
+
+        return null;
+    }
+
+    /**
+     * Same as get_registration except it throws exception if site not registered
+     *
+     * @return stdClass
+     * @throws \moodle_exception
+     */
+    public static function require_registration() {
+        if ($registration = self::get_registration()) {
+            return $registration;
+        }
+        if (has_capability('moodle/site:config', context_system::instance())) {
+            throw new moodle_exception('registrationwarning', 'admin', new moodle_url('/admin/registration/index.php'));
+        } else {
+            throw new moodle_exception('registrationwarningcontactadmin', 'admin');
+        }
+    }
+
+    /**
+     * Checks if site is registered
+     *
+     * @return bool
+     */
+    public static function is_registered() {
+        return self::get_registration() ? true : false;
+    }
+
+    /**
+     * Returns registration token
+     *
+     * @param int $strictness if set to MUST_EXIST and site is not registered will throw an exception
+     * @return null
+     * @throws moodle_exception
+     */
+    public static function get_token($strictness = IGNORE_MISSING) {
+        if ($strictness == MUST_EXIST) {
+            $registration = self::require_registration();
+        } else if (!$registration = self::get_registration()) {
+            return null;
+        }
+        return $registration->token;
+    }
+
+    /**
+     * When was the registration last updated
+     *
+     * @return int|null timestamp or null if site is not registered
+     */
+    public static function get_last_updated() {
+        if ($registration = self::get_registration()) {
+            return $registration->timemodified;
+        }
+        return null;
+    }
+
+    /**
+     * Calculates and prepares site information to send to moodle.net as part of registration or update
+     *
+     * @param array $defaults default values for inputs in the registration form (if site was never registered before)
+     * @return array site info
+     */
+    public static function get_site_info($defaults = []) {
+        global $CFG, $DB;
+        require_once($CFG->libdir . '/badgeslib.php');
+        require_once($CFG->dirroot . "/course/lib.php");
+
+        $siteinfo = array();
+        $cleanhuburl = clean_param(HUB_MOODLEORGHUBURL, PARAM_ALPHANUMEXT);
+        foreach (self::FORM_FIELDS as $field) {
+            $siteinfo[$field] = get_config('hub', 'site_'.$field.'_' . $cleanhuburl);
+            if ($siteinfo[$field] === false && array_key_exists($field, $defaults)) {
+                $siteinfo[$field] = $defaults[$field];
+            }
+        }
+
+        // Statistical data.
+        $siteinfo['courses'] = $DB->count_records('course') - 1;
+        $siteinfo['users'] = $DB->count_records('user', array('deleted' => 0));
+        $siteinfo['enrolments'] = $DB->count_records('role_assignments');
+        $siteinfo['posts'] = $DB->count_records('forum_posts');
+        $siteinfo['questions'] = $DB->count_records('question');
+        $siteinfo['resources'] = $DB->count_records('resource');
+        $siteinfo['badges'] = $DB->count_records_select('badge', 'status <> ' . BADGE_STATUS_ARCHIVED);
+        $siteinfo['issuedbadges'] = $DB->count_records('badge_issued');
+        $siteinfo['participantnumberaverage'] = average_number_of_participants();
+        $siteinfo['modulenumberaverage'] = average_number_of_courses_modules();
+
+        // Version and url.
+        $siteinfo['moodleversion'] = $CFG->version;
+        $siteinfo['moodlerelease'] = $CFG->release;
+        $siteinfo['url'] = $CFG->wwwroot;
+
+        // Mobile related information.
+        $siteinfo['mobileservicesenabled'] = 0;
+        $siteinfo['mobilenotificationsenabled'] = 0;
+        $siteinfo['registereduserdevices'] = 0;
+        $siteinfo['registeredactiveuserdevices'] = 0;
+        if (!empty($CFG->enablewebservices) && !empty($CFG->enablemobilewebservice)) {
+            $siteinfo['mobileservicesenabled'] = 1;
+            $siteinfo['registereduserdevices'] = $DB->count_records('user_devices');
+            $airnotifierextpath = $CFG->dirroot . '/message/output/airnotifier/externallib.php';
+            if (file_exists($airnotifierextpath)) { // Maybe some one uninstalled the plugin.
+                require_once($airnotifierextpath);
+                $siteinfo['mobilenotificationsenabled'] = \message_airnotifier_external::is_system_configured();
+                $siteinfo['registeredactiveuserdevices'] = $DB->count_records('message_airnotifier_devices', array('enable' => 1));
+            }
+        }
+
+        return $siteinfo;
+    }
+
+    /**
+     * Save registration info locally so it can be retrieved when registration needs to be updated
+     *
+     * @param stdClass $formdata data from {@link site_registration_form}
+     */
+    public static function save_site_info($formdata) {
+        $cleanhuburl = clean_param(HUB_MOODLEORGHUBURL, PARAM_ALPHANUMEXT);
+        foreach (self::FORM_FIELDS as $field) {
+            set_config('site_' . $field . '_' . $cleanhuburl, $formdata->$field, 'hub');
+        }
+    }
+
+    /**
+     * Updates site registration when "Update reigstration" button is clicked by admin
+     */
+    public static function update_manual() {
+        global $DB;
+
+        if (!$registration = self::get_registration()) {
+            return false;
+        }
+
+        $siteinfo = self::get_site_info();
+        try {
+            api::update_registration($siteinfo);
+        } catch (moodle_exception $e) {
+            \core\notification::add(get_string('errorregistrationupdate', 'hub', $e->getMessage()),
+                \core\output\notification::NOTIFY_ERROR);
+            return false;
+        }
+        $DB->update_record('registration_hubs', ['id' => $registration->id, 'timemodified' => time()]);
+        \core\notification::add(get_string('siteregistrationupdated', 'hub'),
+            \core\output\notification::NOTIFY_SUCCESS);
+        self::$registration = null;
+        return true;
+    }
+
+    /**
+     * Updates site registration via cron
+     *
+     * @throws moodle_exception
+     */
+    public static function update_cron() {
+        global $DB;
+
+        if (!$registration = self::get_registration()) {
+            mtrace(get_string('registrationwarning', 'admin'));
+            return;
+        }
+
+        $siteinfo = self::get_site_info();
+        api::update_registration($siteinfo);
+        $DB->update_record('registration_hubs', ['id' => $registration->id, 'timemodified' => time()]);
+        mtrace(get_string('siteregistrationupdated', 'hub'));
+        self::$registration = null;
+    }
+
+    /**
+     * Confirms registration by moodle.net
+     *
+     * @param string $token
+     * @param string $newtoken
+     * @param string $hubname
+     * @throws moodle_exception
+     */
+    public static function confirm_registration($token, $newtoken, $hubname) {
+        global $DB;
+
+        $registration = self::get_registration(false);
+        if (!$registration || $registration->token !== $token) {
+            throw new moodle_exception('wrongtoken', 'hub', new moodle_url('/admin/registration/index.php'));
+        }
+        $record = ['id' => $registration->id];
+        $record['token'] = $newtoken;
+        $record['confirmed'] = 1;
+        $record['hubname'] = $hubname;
+        $record['timemodified'] = time();
+        $DB->update_record('registration_hubs', $record);
+        self::$registration = null;
+    }
+
+    /**
+     * Retrieve the options for site privacy form element to use in registration form
+     * @return array
+     */
+    public static function site_privacy_options() {
+        return [
+            self::HUB_SITENOTPUBLISHED => get_string('siteprivacynotpublished', 'hub'),
+            self::HUB_SITENAMEPUBLISHED => get_string('siteprivacypublished', 'hub'),
+            self::HUB_SITELINKPUBLISHED => get_string('siteprivacylinked', 'hub')
+        ];
+    }
+
+    /**
+     * Registers a site
+     *
+     * This method will make sure that unconfirmed registration record is created and then redirect to
+     * registration script on https://moodle.net
+     * Moodle.net will check that the site is accessible, register it and redirect back
+     * to /admin/registration/confirmregistration.php
+     *
+     * @throws \coding_exception
+     */
+    public static function register() {
+        global $DB;
+
+        if (self::is_registered()) {
+            // Caller of this method must make sure that site is not registered.
+            throw new \coding_exception('Site already registered');
+        }
+
+        $hub = self::get_registration(false);
+        if (empty($hub)) {
+            // Create a new record in 'registration_hubs'.
+            $hub = new stdClass();
+            $hub->token = get_site_identifier();
+            $hub->secret = $hub->token;
+            $hub->huburl = HUB_MOODLEORGHUBURL;
+            $hub->hubname = 'Moodle.net';
+            $hub->confirmed = 0;
+            $hub->timemodified = time();
+            $hub->id = $DB->insert_record('registration_hubs', $hub);
+            self::$registration = null;
+        }
+
+        $params = self::get_site_info();
+        $params['token'] = $hub->token;
+
+        redirect(new moodle_url(HUB_MOODLEORGHUBURL . '/local/hub/siteregistration.php', $params));
+    }
+
+    /**
+     * Unregister site
+     *
+     * @param bool $unpublishalladvertisedcourses
+     * @param bool $unpublishalluploadedcourses
+     * @return bool
+     */
+    public static function unregister($unpublishalladvertisedcourses, $unpublishalluploadedcourses) {
+        global $DB;
+
+        if (!$hub = self::get_registration()) {
+            return true;
+        }
+
+        // Unpublish the courses.
+        try {
+            publication::delete_all_publications($unpublishalladvertisedcourses, $unpublishalluploadedcourses);
+        } catch (moodle_exception $e) {
+            $errormessage = $e->getMessage();
+            $errormessage .= \html_writer::empty_tag('br') .
+                get_string('errorunpublishcourses', 'hub');
+
+            \core\notification::add(get_string('unregistrationerror', 'hub', $errormessage),
+                \core\output\notification::NOTIFY_ERROR);
+            return false;
+        }
+
+        // Course unpublish went ok, unregister the site now.
+        try {
+            api::unregister_site();
+        } catch (moodle_exception $e) {
+            \core\notification::add(get_string('unregistrationerror', 'hub', $e->getMessage()),
+                \core\output\notification::NOTIFY_ERROR);
+            return false;
+        }
+
+        $DB->delete_records('registration_hubs', array('id' => $hub->id));
+        self::$registration = null;
+        return true;
+    }
+
+    /**
+     * Generate a new token for the site that is not registered
+     *
+     * @param string $token
+     * @throws moodle_exception
+     */
+    public static function reset_site_identifier($token) {
+        global $DB, $CFG;
+
+        $registration = self::get_registration(false);
+        if (!$registration || $registration->token != $token) {
+            throw new moodle_exception('wrongtoken', 'hub',
+               new moodle_url('/admin/registration/index.php'));
+        }
+
+        $DB->delete_records('registration_hubs', array('id' => $registration->id));
+        self::$registration = null;
+
+        $CFG->siteidentifier = null;
+        get_site_identifier();
+    }
+
+    /**
+     * Returns information about moodle.net
+     *
+     * Example of the return array:
+     * {
+     *     "courses": 384,
+     *     "description": "Moodle.net connects you with free content and courses shared by Moodle ...",
+     *     "downloadablecourses": 190,
+     *     "enrollablecourses": 194,
+     *     "hublogo": 1,
+     *     "language": "en",
+     *     "name": "Moodle.net",
+     *     "sites": 274175,
+     *     "url": "https://moodle.net",
+     *     "imgurl": moodle_url : "https://moodle.net/local/hub/webservice/download.php?filetype=hubscreenshot"
+     * }
+     *
+     * @return array|null
+     */
+    public static function get_moodlenet_info() {
+        try {
+            return api::get_hub_info();
+        } catch (moodle_exception $e) {
+            // Ignore error, we only need it for displaying information about moodle.net, if this request
+            // fails, it's not a big deal.
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/classes/hub/site_registration_form.php b/lib/classes/hub/site_registration_form.php
new file mode 100644 (file)
index 0000000..f6f69e6
--- /dev/null
@@ -0,0 +1,226 @@
+<?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 site_registration_form
+ *
+ * @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 context_course;
+
+global $CFG;
+require_once($CFG->libdir . '/formslib.php');
+
+/**
+ * The site registration form. Information will be sent to moodle.net
+ *
+ * @author     Jerome Mouneyrac <jerome@mouneyrac.com>
+ * @package    core
+ * @copyright  2017 Marina Glancy
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class site_registration_form extends \moodleform {
+
+    /**
+     * Form definition
+     */
+    public function definition() {
+        global $CFG;
+
+        $strrequired = get_string('required');
+        $mform = & $this->_form;
+        $admin = get_admin();
+        $site = get_site();
+
+        $siteinfo = registration::get_site_info([
+            'name' => format_string($site->fullname, true, array('context' => context_course::instance(SITEID))),
+            'description' => $site->summary,
+            'contactname' => fullname($admin, true),
+            'contactemail' => $admin->email,
+            'contactphone' => $admin->phone1,
+            'street' => '',
+            'countrycode' => $admin->country ?: $CFG->country,
+            'regioncode' => '-', // Not supported yet.
+            'language' => explode('_', current_language())[0],
+            'geolocation' => '',
+            'emailalert' => 1,
+
+        ]);
+
+        $mform->addElement('header', 'moodle', get_string('registrationinfo', 'hub'));
+
+        $mform->addElement('text', 'name', get_string('sitename', 'hub'),
+            array('class' => 'registration_textfield'));
+        $mform->addRule('name', $strrequired, 'required', null, 'client');
+        $mform->setType('name', PARAM_TEXT);
+        $mform->addHelpButton('name', 'sitename', 'hub');
+
+        $mform->addElement('select', 'privacy', get_string('siteprivacy', 'hub'), registration::site_privacy_options());
+        $mform->setType('privacy', PARAM_ALPHA);
+        $mform->addHelpButton('privacy', 'privacy', 'hub');
+        unset($options);
+
+        $mform->addElement('textarea', 'description', get_string('sitedesc', 'hub'),
+            array('rows' => 8, 'cols' => 41));
+        $mform->addRule('description', $strrequired, 'required', null, 'client');
+        $mform->setType('description', PARAM_TEXT);
+        $mform->addHelpButton('description', 'sitedesc', 'hub');
+
+        $languages = get_string_manager()->get_list_of_languages();
+        \core_collator::asort($languages);
+        $mform->addElement('select', 'language', get_string('sitelang', 'hub'), $languages);
+        $mform->setType('language', PARAM_ALPHANUMEXT);
+        $mform->addHelpButton('language', 'sitelang', 'hub');
+
+        $mform->addElement('textarea', 'street', get_string('postaladdress', 'hub'),
+            array('rows' => 4, 'cols' => 41));
+        $mform->setType('street', PARAM_TEXT);
+        $mform->addHelpButton('street', 'postaladdress', 'hub');
+
+        $mform->addElement('hidden', 'regioncode', '-');
+        $mform->setType('regioncode', PARAM_ALPHANUMEXT);
+
+        $countries = ['' => ''] + get_string_manager()->get_list_of_countries();
+        $mform->addElement('select', 'countrycode', get_string('sitecountry', 'hub'), $countries);
+        $mform->setType('countrycode', PARAM_ALPHANUMEXT);
+        $mform->addHelpButton('countrycode', 'sitecountry', 'hub');
+        $mform->addRule('countrycode', $strrequired, 'required', null, 'client');
+
+        $mform->addElement('text', 'geolocation', get_string('sitegeolocation', 'hub'),
+            array('class' => 'registration_textfield'));
+        $mform->setType('geolocation', PARAM_RAW);
+        $mform->addHelpButton('geolocation', 'sitegeolocation', 'hub');
+
+        $mform->addElement('text', 'contactname', get_string('siteadmin', 'hub'),
+            array('class' => 'registration_textfield'));
+        $mform->addRule('contactname', $strrequired, 'required', null, 'client');
+        $mform->setType('contactname', PARAM_TEXT);
+        $mform->addHelpButton('contactname', 'siteadmin', 'hub');
+
+        $mform->addElement('text', 'contactphone', get_string('sitephone', 'hub'),
+            array('class' => 'registration_textfield'));
+        $mform->setType('contactphone', PARAM_TEXT);
+        $mform->addHelpButton('contactphone', 'sitephone', 'hub');
+        $mform->setForceLtr('contactphone');
+
+        $mform->addElement('text', 'contactemail', get_string('siteemail', 'hub'),
+            array('class' => 'registration_textfield'));
+        $mform->addRule('contactemail', $strrequired, 'required', null, 'client');
+        $mform->setType('contactemail', PARAM_EMAIL);
+        $mform->addHelpButton('contactemail', 'siteemail', 'hub');
+
+        $options = array();
+        $options[0] = get_string("registrationcontactno");
+        $options[1] = get_string("registrationcontactyes");
+        $mform->addElement('select', 'contactable', get_string('siteregistrationcontact', 'hub'), $options);
+        $mform->setType('contactable', PARAM_INT);
+        $mform->addHelpButton('contactable', 'siteregistrationcontact', 'hub');
+        unset($options);
+
+        $options = array();
+        $options[0] = get_string("registrationno");
+        $options[1] = get_string("registrationyes");
+        $mform->addElement('select', 'emailalert', get_string('siteregistrationemail', 'hub'), $options);
+        $mform->setType('emailalert', PARAM_INT);
+        $mform->addHelpButton('emailalert', 'siteregistrationemail', 'hub');
+        unset($options);
+
+        // TODO site logo.
+        $mform->addElement('hidden', 'imageurl', ''); // TODO: temporary.
+        $mform->setType('imageurl', PARAM_URL);
+
+        $mform->addElement('static', 'urlstring', get_string('siteurl', 'hub'), $siteinfo['url']);
+        $mform->addHelpButton('urlstring', 'siteurl', 'hub');
+
+        $mform->addElement('static', 'versionstring', get_string('siteversion', 'hub'), $CFG->version);
+        $mform->addElement('hidden', 'moodleversion', $siteinfo['moodleversion']);
+        $mform->setType('moodleversion', PARAM_INT);
+        $mform->addHelpButton('versionstring', 'siteversion', 'hub');
+
+        $mform->addElement('static', 'releasestring', get_string('siterelease', 'hub'), $CFG->release);
+        $mform->addElement('hidden', 'moodlerelease', $siteinfo['moodlerelease']);
+        $mform->setType('moodlerelease', PARAM_TEXT);
+        $mform->addHelpButton('releasestring', 'siterelease', 'hub');
+
+        // Display statistic that are going to be retrieve by moodle.net.
+
+        $mform->addElement('static', 'courseslabel', get_string('sendfollowinginfo', 'hub'),
+            " " . get_string('coursesnumber', 'hub', $siteinfo['courses']));
+        $mform->addHelpButton('courseslabel', 'sendfollowinginfo', 'hub');
+
+        $mform->addElement('static', 'userslabel', '',
+            " " . get_string('usersnumber', 'hub', $siteinfo['users']));
+
+        $mform->addElement('static', 'roleassignmentslabel', '',
+            " " . get_string('roleassignmentsnumber', 'hub', $siteinfo['enrolments']));
+
+        $mform->addElement('static', 'postslabel', '',
+            " " . get_string('postsnumber', 'hub', $siteinfo['posts']));
+
+        $mform->addElement('static', 'questionslabel', '',
+            " " . get_string('questionsnumber', 'hub', $siteinfo['questions']));
+
+        $mform->addElement('static', 'resourceslabel', '',
+            " " . get_string('resourcesnumber', 'hub', $siteinfo['resources']));
+
+        $mform->addElement('static', 'badgeslabel', '',
+            " " . get_string('badgesnumber', 'hub', $siteinfo['badges']));
+
+        $mform->addElement('static', 'issuedbadgeslabel', '',
+            " " . get_string('issuedbadgesnumber', 'hub', $siteinfo['issuedbadges']));
+
+        $mform->addElement('static', 'participantnumberaveragelabel', '',
+            " " . get_string('participantnumberaverage', 'hub', $siteinfo['participantnumberaverage']));
+
+        $mform->addElement('static', 'modulenumberaveragelabel', '',
+            " " . get_string('modulenumberaverage', 'hub', $siteinfo['modulenumberaverage']));
+
+        $mobileservicestatus = $siteinfo['mobileservicesenabled'] ? get_string('yes') : get_string('no');
+        $mform->addElement('static', 'mobileservicesenabledlabel', '',
+            " " . get_string('mobileservicesenabled', 'hub', $mobileservicestatus));
+
+        $mobilenotificationsstatus = $siteinfo['mobilenotificationsenabled'] ? get_string('yes') : get_string('no');
+        $mform->addElement('static', 'mobilenotificationsenabledlabel', '',
+            " " . get_string('mobilenotificationsenabled', 'hub', $mobilenotificationsstatus));
+
+        $mform->addElement('static', 'registereduserdeviceslabel', '',
+            " " . get_string('registereduserdevices', 'hub', $siteinfo['registereduserdevices']));
+
+        $mform->addElement('static', 'registeredactiveuserdeviceslabel', '',
+            " " . get_string('registeredactiveuserdevices', 'hub', $siteinfo['registeredactiveuserdevices']));
+
+        // Check if it's a first registration or update.
+        if (registration::is_registered()) {
+            $buttonlabel = get_string('updatesite', 'hub', 'Moodle.net');
+            $mform->addElement('hidden', 'update', true);
+            $mform->setType('update', PARAM_BOOL);
+        } else {
+            $buttonlabel = get_string('registersite', 'hub', 'Moodle.net');
+        }
+
+        $this->add_action_buttons(false, $buttonlabel);
+
+        $this->set_data($siteinfo);
+    }
+
+}
+
diff --git a/lib/classes/hub/site_unregistration_form.php b/lib/classes/hub/site_unregistration_form.php
new file mode 100644 (file)
index 0000000..ed4116a
--- /dev/null
@@ -0,0 +1,61 @@
+<?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 site_unregistration_form
+ *
+ * @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();
+
+global $CFG;
+require_once($CFG->libdir . '/formslib.php');
+
+/**
+ * This form display a unregistration form.
+ *
+ * @author     Jerome Mouneyrac <jerome@mouneyrac.com>
+ * @package    core
+ * @copyright  2017 Marina Glancy
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class site_unregistration_form extends \moodleform {
+
+    /**
+     * Form definition
+     */
+    public function definition() {
+        $mform = & $this->_form;
+        $mform->addElement('header', 'site', get_string('unregister', 'hub'));
+
+        $unregisterlabel = get_string('unregister', 'hub');
+        $mform->addElement('advcheckbox', 'unpublishalladvertisedcourses', '',
+            ' ' . get_string('unpublishalladvertisedcourses', 'hub'));
+        $mform->setType('unpublishalladvertisedcourses', PARAM_INT);
+        $mform->addElement('advcheckbox', 'unpublishalluploadedcourses', '',
+            ' ' . get_string('unpublishalluploadedcourses', 'hub'));
+        $mform->setType('unpublishalluploadedcourses', PARAM_INT);
+
+        $mform->addElement('hidden', 'unregistration', 1);
+        $mform->setType('unregistration', PARAM_INT);
+
+        $this->add_action_buttons(true, $unregisterlabel);
+    }
+}