require_once $CFG->dirroot . '/local/hub/lib.php'; require_once $CFG->dirroot . '/course/publish/lib.php'; //HUB_SCREENSHOT_FILE_TYPE and HUB_BACKUP_FILE_TYPE $token = optional_param('token', '', PARAM_ALPHANUM); $filetype = optional_param('filetype', '', PARAM_ALPHA); //can be screenshots, backup, ... $screenshotnumber = optional_param('screenshotnumber', 1, PARAM_INT); //the screenshot number of this course $courseid = optional_param('courseid', '', PARAM_ALPHANUM); // check the communication token $hub = new local_hub(); $communication = $hub->get_communication(WSSERVER, REGISTEREDSITE, '', $token); if (!empty($token) && !empty($communication) and get_config('local_hub', 'hubenabled')) { //retrieve the site $siteurl = $communication->remoteurl; $site = $hub->get_site_by_url($siteurl); //check that the course exist $course = $DB->get_record('hub_course_directory', array('id' => $courseid, 'siteid' => $site->id)); if (!empty($course) && !empty($_FILES)) { switch ($filetype) { case HUB_BACKUP_FILE_TYPE: //check that the backup doesn't already exist $backup = $hub->backup_exits($courseid); if (empty($backup)) { $hub->add_backup($_FILES['file'], $courseid); } break; case HUB_SCREENSHOT_FILE_TYPE: $hub->add_screenshot($_FILES['file'], $courseid, $screenshotnumber); break; }
} // Check if the remote site is available. if (!$hub->is_remote_site_valid($url)) { $port = parse_url($url, PHP_URL_PORT); if (!empty($port) && $port != 80 && $port != 443) { throw new moodle_exception('cannotregisterbadport', 'local_hub', $url, $url); } throw new moodle_exception('cannotregisternotavailablesite', 'local_hub', $url, $url); } //check if the registration password is correct $hubpassword = get_config('local_hub', 'password'); if (!empty($hubpassword) and $hubpassword != $password) { throw new moodle_exception('wronghubpassword', 'local_hub', $url . '/admin/registration/hubselector.php'); } //check if the site url is already registered $sitewithsameurl = $hub->get_site_by_url($url); if (!empty($sitewithsameurl)) { $urlexists = true; } else { $urlexists = false; } //check if the secret already exists $sitewithsamesecret = $hub->get_site_by_secret(md5($token)); if (!empty($sitewithsamesecret)) { $secretexists = true; } else { $secretexists = false; } if ($secretexists and !$urlexists) { //the site has been moved or the site has been copied $action = optional_param('action', '', PARAM_ALPHA);
/** * Updates sites data (from moodle.org) into {hub_sites_directory} in moodle.net (hub.moodle.org) * @return object */ public static function sync_into_sitesregister($sites) { global $DB; // Ensure the current user is allowed to run this function $context = context_system::instance(); self::validate_context($context); require_capability('local/hub:viewinfo', $context); $returnable = new stdClass(); try { $params = self::validate_parameters(self::sync_into_sitesregister_parameters(), array('newdatasince' => $sites)); } catch (invalid_parameter_exception $ex) { // record and send back later - but try individual records (with individual stricter validation) $returnable->exception = $ex->debuginfo; } //do our own additional validation (to circumvent core and proceed with using/replacing nulls.) $nullablefields = array('hubid', 'url', 'name', 'description', 'moodleversion', 'moodlerelease', 'serverstring', 'host', 'ip', 'language', 'secret', 'countrycode', 'deleted', 'publicationmax', 'regioncode', 'street', 'geolocation', 'contactname', 'contactemail', 'contactphone', 'imageurl', 'privacy', 'confirmed', 'redirectto', 'latitude', 'longitude'); $nullable_map = array('name' => ' ', 'deleted' => 0, 'publicationmax' => null); //what they should be in mdl_hub_site_directory $hub = new local_hub(); $syncerecs = array(); foreach ($params['newdatasince'] as $registrysite) { try { $syncrec = new stdClass(); //used in catch so we'll init here. $registrysite = (object) $registrysite; $syncrec->id = $registrysite->id; $syncrec->hubid = null; $objvars = get_object_vars($registrysite); //convert back to null and run extra validation. foreach ($objvars as $prop => $val) { if ($registrysite->otpnull === $val) { //got a null marker. if (array_key_exists($prop, $nullable_map)) { $registrysite->{$prop} = $nullable_map[$prop]; } else { if (in_array($prop, $nullablefields)) { //check on agreed nullables (remove if this is too restrictive in future) $registrysite->{$prop} = null; } } } } //drop otpnull and revalidate. unset($registrysite->otpnull); try { $registrysite = (object) self::validate_parameters(self::sync_into_sitesregister_parameters_safe(), (array) $registrysite); } catch (invalid_parameter_exception $ex) { //allow if it had been confirmed during moodle.org registration process. if (strpos($ex->debuginfo, 'url') == 0) { //exception starts with fieldname. if ($registrysite->confirmed == 0) { throw $ex; } } else { throw $ex; } } // if not the same, merge legacy 'mailme' into 'contactable' for hub. if ($registrysite->mailme != $registrysite->contactable) { //somewhere contactable was brought to registry@moodle.org. only 1.9 site registration uses mailme. $registrysite->contactable = $registrysite->mailme; // 1.9 changes to mailme brought through to hub. (this is a quick fix to a mess) @todo cleanup } //fix some common data length errors - just truncate (original is stored in moodle.org registry and a 2.x upgrade can fix it at hub) if (strlen($registrysite->moodlerelease) > 50) { $registrysite->moodlerelease = substr($registrysite->moodlerelease, 0, 49); } if (strlen($registrysite->ip) > 45) { $registrysite->ip = substr($registrysite->ip, 0, 44); } if (mb_detect_encoding($registrysite->name) == 'UTF-8' && mb_strlen($registrysite->name) > 255) { $registrysite->name = mb_substr($registrysite->name, 0, 246); //truncate must be mb safe!... } else { if (strlen($registrysite->name) > 255) { $registrysite->name = substr($registrysite->name, 0, 248); } } if (strlen($registrysite->countrycode) > 2) { $registrysite->countrycode = 'ZZ'; //the code for unknown country. solve this later in some checker. } if ($registrysite->hubid > 0) { // update this record $registrysite->id = $registrysite->hubid; unset($registrysite->hubid); // we don't care about registry ids at hub. $registrysite->unreachable = 0; //updated site means we should re-check this. $hub->update_site($registrysite); // has its own timemodified stamp $syncrec->hubid = $registrysite->id; // regsiteid -> hubid } else { if ($registrysite->hubid == null) { // add new unsycned site record // check! (remote may have failed in updating hubid, so this may just be an old skippable update to try again) unset($registrysite->id); unset($registrysite->hubid); $hubsite = $hub->add_site($registrysite, true); // has its own timecreated stamp $syncrec->hubid = $hubsite->id; } else { // just try to see if there is any match by url. (hubid would be < 1 to indicate previously failed syncs) $matchedsite = $hub->get_site_by_url($registrysite->url); if ($matchedsite && $registrysite->hubid < 1 && $matchedsite->secret == $registrysite->secret) { foreach (get_object_vars($registrysite) as $prop => $val) { if (isset($matchedsite->{$prop})) { $matchedsite->{$prop} = $val; } } $hub->update_site($matchedsite); $syncrec->hubid = $matchedsite->id; } } } } catch (Exception $ex) { // don't limit type of exception - carry on for all exceptions since we're working per record now. $syncrec->exception = $ex->debuginfo; } if (isset($syncrec->exception)) { error_log('sync_into_sitesregister() failed processing id ' . $syncrec->id); error_log('hubid ' . $syncrec->hubid); error_log('url ' . $registrysite->url); $syncrec->exception = utf8_encode($syncrec->exception); //avoid character codings (non-utf8) causing response validation errors. error_log('exception: ' . $syncrec->exception); } $syncerecs[] = $syncrec; } $returnable->reghubidmap = $syncerecs; $returnable->timesynced = time(); return $returnable; }