Esempio n. 1
0
 /**
  * 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;
 }