/**
  * Execute the command.
  * @param mixed $hosts The host where run the command (may be wwwroot or an array).
  * @throws Command_Exception.
  */
 public function run($hosts)
 {
     global $CFG, $USER;
     // Adding constants.
     require_once $CFG->dirroot . '/local/vmoodle/rpclib.php';
     // Checking capabilities.
     if (!has_capability('local/vmoodle:execute', \context_system::instance())) {
         throw new Command_Exception('insuffisantcapabilities');
     }
     // Getting role
     $table = $this->getParameter('table')->getValue();
     // Creating XMLRPC client to read role configuration
     $rpc_client = new \local_vmoodle\XmlRpc_Client();
     $rpc_client->set_method('local/vmoodle/plugins/roles/rpclib.php/mnetadmin_rpc_get_role_allow_table');
     $rpc_client->add_param($table, 'string');
     $rpc_client->add_param('', 'string');
     // get for all roles
     // Initializing responses
     $responses = array();
     // Creating peers.
     $mnet_hosts = array();
     foreach ($hosts as $host => $name) {
         $mnet_host = new \mnet_peer();
         if ($mnet_host->bootstrap($host, null, 'moodle')) {
             $mnet_hosts[] = $mnet_host;
         } else {
             $responses[$host] = (object) array('status' => MNET_FAILURE, 'error' => get_string('couldnotcreateclient', 'local_vmoodle', $host));
         }
     }
     // Sending requests.
     foreach ($mnet_hosts as $mnet_host) {
         // Sending request.
         if (!$rpc_client->send($mnet_host)) {
             $response = new \StdClass();
             $response->status = MNET_FAILURE;
             $response->errors[] = implode('<br/>', $rpc_client->getErrors($mnet_host));
             if (debugging()) {
                 echo '<pre>';
                 var_dump($rpc_client);
                 echo '</pre>';
             }
         } else {
             $response = json_decode($rpc_client->response);
         }
         // Recording response.
         $responses[$mnet_host->wwwroot] = $response;
         // Recording capabilities.
         if ($response->status == RPC_SUCCESS) {
             $this->capabilities[$mnet_host->wwwroot] = $response->value;
         }
     }
     // Saving results.
     $this->results = $responses + $this->results;
     // Processing results.
     $this->_process();
 }
 /**
  * Execute the command.
  * @param mixed $host The hosts where run the command (may be wwwroot or an array).
  * @throws Command_Maintenance_Exception
  */
 public function run($hosts)
 {
     global $CFG, $USER;
     // Adding constants.
     require_once $CFG->dirroot . '/local/vmoodle/rpclib.php';
     // Checking host.
     if (!is_array($hosts)) {
         $hosts = array($hosts => 'Unnamed host');
     }
     // Checking capabilities.
     if (!has_capability('local/vmoodle:execute', \context_system::instance())) {
         throw new Command_PurgeCaches_Exception('insuffisantcapabilities');
     }
     // Initializing responses.
     $responses = array();
     // Creating peers.
     $mnet_hosts = array();
     foreach ($hosts as $host => $name) {
         $mnet_host = new \mnet_peer();
         if ($mnet_host->bootstrap($host, null, 'moodle')) {
             $mnet_hosts[] = $mnet_host;
         } else {
             $responses[$host] = (object) array('status' => RPC_FAILURE, 'error' => get_string('couldnotcreateclient', 'local_vmoodle', $host));
         }
     }
     // Getting command.
     $command = $this->isReturned();
     // Creating XMLRPC client.
     $rpc_client = new \local_vmoodle\XmlRpc_Client();
     $rpc_client->set_method('local/vmoodle/plugins/generic/rpclib.php/mnetadmin_rpc_purge_caches');
     // Sending requests.
     foreach ($mnet_hosts as $mnet_host) {
         // Sending request
         if (!$rpc_client->send($mnet_host)) {
             $response = new StdClass();
             $response->status = RPC_FAILURE;
             $response->errors[] = implode('<br/>', $rpc_client->getErrors($mnet_host));
             if (debugging()) {
                 echo '<pre>';
                 var_dump($rpc_client);
                 echo '</pre>';
             }
         } else {
             $response = json_decode($rpc_client->response);
         }
         // Recording response
         $responses[$mnet_host->wwwroot] = $response;
     }
     // Saving results.
     $this->results = $responses + $this->results;
 }
     $rpc_client->set_method('local/vmoodle/rpclib.php/mnetadmin_rpc_unbind_peer');
     $rpc_client->add_param($vmoodle->vhostname, 'string');
     foreach ($subnetwork_hosts as $subnetwork_host) {
         $temp_member = new mnet_peer();
         $temp_member->set_wwwroot($subnetwork_host->wwwroot);
         // RPC error.
         if (!$rpc_client->send($temp_member)) {
             echo $OUTPUT->notification(implode('<br />', $rpc_client->getErrors($temp_member)));
             if (debugging()) {
                 echo '<pre>';
                 var_dump($rpc_client);
                 echo '</pre>';
             }
         }
     }
     $rpc_client = new \local_vmoodle\XmlRpc_Client();
     $rpc_client->set_method('local/vmoodle/rpclib.php/mnetadmin_rpc_disconnect_from_subnetwork');
     $rpc_client->add_param($subnetwork_hosts, 'array');
     $deleted_peer = new mnet_peer();
     $deleted_peer->set_wwwroot($vmoodle_host->wwwroot);
     // RPC error.
     if (!$rpc_client->send($deleted_peer)) {
         echo $OUTPUT->notification(implode('<br />', $rpc_client->getErrors($deleted_peer)));
         if (debugging()) {
             echo '<pre>';
             var_dump($rpc_client);
             echo '</pre>';
         }
     }
 }
 // Every step was SUCCESS.
 public function run($hosts)
 {
     global $CFG, $USER, $DB;
     // Adding constants.
     require_once $CFG->dirroot . '/local/vmoodle/rpclib.php';
     // Checking host.
     if (!is_array($hosts)) {
         $hosts = array($hosts => 'Unnamed host');
     }
     // Checking capabilities.
     if (!has_capability('local/vmoodle:execute', \context_system::instance())) {
         throw new Command_Upgrade_Exception('insuffisantcapabilities');
     }
     // Initializing responses.
     $responses = array();
     // Creating peers.
     $mnet_hosts = array();
     foreach ($hosts as $host => $name) {
         $mnet_host = new \mnet_peer();
         if ($mnet_host->bootstrap($host, null, 'moodle')) {
             $mnet_hosts[] = $mnet_host;
         } else {
             $responses[$host] = (object) array('status' => RPC_FAILURE, 'error' => get_string('couldnotcreateclient', 'local_vmoodle', $host));
         }
     }
     // Creating XMLRPC client.
     $rpc_client = new \local_vmoodle\XmlRpc_Client();
     $rpc_client->set_method('local/vmoodle/plugins/upgrade/rpclib.php/mnetadmin_rpc_upgrade');
     // Sending requests
     foreach ($mnet_hosts as $mnet_host) {
         /**
         * just for testing
         if ($mnet_host->wwwroot == $CFG->wwwroot){
             require_once $CFG->dirroot.'/local/vmoodle/plugins/upgrade/rpclib.php';
             if (!($user_mnet_host = $DB->get_record('mnet_host', array('id' => $USER->mnethostid))))
                 throw new Command_Exception('unknownuserhost');
             $user = array(
                         'username' => $USER->username,
                         'remoteuserhostroot' => $user_mnet_host->wwwroot,
                         'remotehostroot' => $CFG->wwwroot
                     );
             $response = mnetadmin_rpc_upgrade($user, true);
             $responses[$mnet_host->wwwroot] = $response;
             continue;
         }
         */
         // Sending request
         if (!$rpc_client->send($mnet_host)) {
             $response = new StdClass();
             $response->status = RPC_FAILURE;
             $response->errors[] = implode('<br/>', $rpc_client->getErrors($mnet_host));
             if (debugging()) {
                 // echo '<pre>';
                 // var_dump($rpc_client);
                 // echo '</pre>';
             }
         } else {
             $response = json_decode($rpc_client->response);
         }
         // Recording response.
         $responses[$mnet_host->wwwroot] = $response;
     }
     // Saving results.
     $this->results = $responses + $this->results;
 }
 /**
  * Execute the command.
  * @param mixed $hosts The host where run the command (may be wwwroot or an array).
  * @throws Command_Exception.
  */
 public function run($hosts)
 {
     global $CFG, $USER;
     // Adding constants.
     require_once $CFG->dirroot . '/local/vmoodle/rpclib.php';
     // Checking capabilities.
     if (!has_capability('local/vmoodle:execute', \context_system::instance())) {
         throw new Command_Exception('insuffisantcapabilities');
     }
     // Getting role.
     $role = $this->getParameter('role')->getValue();
     // Getting platform.
     $platform = $this->getParameter('platform')->getValue();
     // Getting capability.
     $capability = $this->getParameter('capability')->getValue();
     // Checking hosts.
     if (array_key_exists($platform, $hosts)) {
         $platforms = get_available_platforms();
         throw new Command_Role_Exception('syncwithitself', (object) array('role' => $role, 'platform' => $platforms[$platform]));
     }
     // Creating peer to read role configuration.
     $mnet_host = new \mnet_peer();
     if (!$mnet_host->bootstrap($this->getParameter('platform')->getValue(), null, 'moodle')) {
         $response = (object) array('status' => MNET_FAILURE, 'error' => get_string('couldnotcreateclient', 'local_vmoodle', $platform));
         foreach ($hosts as $host => $name) {
             $this->results[$host] = $response;
         }
         return;
     }
     // Creating XMLRPC client to read role configuration.
     $rpc_client = new \local_vmoodle\XmlRpc_Client();
     $rpc_client->set_method('local/vmoodle/plugins/roles/rpclib.php/mnetadmin_rpc_get_role_capabilities');
     $rpc_client->add_param($role, 'string');
     $rpc_client->add_param($capability, 'string');
     // Checking result.
     if (!($rpc_client->send($mnet_host) && ($response = json_decode($rpc_client->response)) && ($response->status == RPC_SUCCESS || $response->status == RPC_FAILURE_RECORD && (in_array($response->errors, 'No capabilites for this role.') || in_array($response->error, 'No role capability found.'))))) {
         // Creating response.
         if (!isset($response)) {
             $response = new \StdClass();
             $response->status = MNET_FAILURE;
             $response->errors[] = implode('<br/>', $rpc_client->getErrors($mnet_host));
         }
         if (debugging()) {
             echo '<pre>';
             var_dump($rpc_client);
             ob_flush();
             echo '</pre>';
         }
         // Saving results.
         foreach ($hosts as $host => $name) {
             $this->results[$host] = $response;
         }
         return;
     }
     // Getting role configuration.
     if ($response->status == RPC_FAILURE_RECORD) {
         $role_capability = array($capability => null);
     } else {
         $role_capability = (array) $response->value;
     }
     unset($response);
     // Initializing responses.
     $responses = array();
     // Creating peers.
     $mnet_hosts = array();
     foreach ($hosts as $host => $name) {
         $mnet_host = new \mnet_peer();
         if ($mnet_host->bootstrap($host, null, 'moodle')) {
             $mnet_hosts[] = $mnet_host;
         } else {
             $responses[$host] = (object) array('status' => MNET_FAILURE, 'error' => get_string('couldnotcreateclient', 'local_vmoodle', $host));
         }
     }
     // Creating XMLRPC client.
     $rpc_client = new \local_vmoodle\XmlRpc_Client();
     $rpc_client->set_method('local/vmoodle/plugins/roles/rpclib.php/mnetadmin_rpc_set_role_capabilities');
     $rpc_client->add_param($role, 'string');
     $rpc_client->add_param($role_capability, 'string');
     $rpc_client->add_param(false, 'boolean');
     // Sending requests.
     foreach ($mnet_hosts as $mnet_host) {
         // Sending request.
         if (!$rpc_client->send($mnet_host)) {
             $response = new \StdClass();
             $response->status = MNET_FAILURE;
             $response->errors[] = implode('<br/>', $rpc_client->getErrors($mnet_host));
             $response->error = 'Remote Set role capability : Remote proc error';
             if (debugging()) {
                 echo '<pre>';
                 var_dump($rpc_client);
                 ob_flush();
                 echo '</pre>';
             }
         } else {
             $response = json_decode($rpc_client->response);
             $response->errors[] = implode('<br/>', $response->errors);
         }
         // Recording response
         $responses[$mnet_host->wwwroot] = $response;
     }
     // Saving results
     $this->results = $responses + $this->results;
 }
 /**
  * Execute the command.
  * @param mixed $host The hosts where run the command (may be wwwroot or an array).
  * @throws Command_Sql_Exception
  */
 public function run($hosts)
 {
     global $CFG, $USER;
     // Adding constants.
     require_once $CFG->dirroot . '/local/vmoodle/rpclib.php';
     // Checking host.
     if (!is_array($hosts)) {
         $hosts = array($hosts => 'Unnamed host');
     }
     // Checking capabilities.
     if (!has_capability('local/vmoodle:execute', \context_system::instance())) {
         throw new Command_Sql_Exception('insuffisantcapabilities');
     }
     // Initializing responses.
     $responses = array();
     // Creating peers.
     $mnet_hosts = array();
     foreach ($hosts as $host => $name) {
         $mnet_host = new \mnet_peer();
         if ($mnet_host->bootstrap($host, null, 'moodle')) {
             $mnet_hosts[] = $mnet_host;
         } else {
             $responses[$host] = (object) array('status' => MNET_FAILURE, 'error' => get_string('couldnotcreateclient', 'local_vmoodle', $host));
         }
     }
     // Getting command.
     // $command = $this->isReturned();
     // Creating XMLRPC client.
     $rpc_client = new \local_vmoodle\XmlRpc_Client();
     $rpc_client->set_method('local/vmoodle/plugins/sql/rpclib.php/mnetadmin_rpc_run_sql_command');
     $rpc_client->add_param($this->_getGeneratedCommand(), 'string');
     $rpc_client->add_param($this->values, 'array');
     $rpc_client->add_param(false, 'boolean');
     $rpc_client->add_param(true, 'boolean');
     // telling other side we are a multiple command
     // Sending requests.
     foreach ($mnet_hosts as $mnet_host) {
         // Sending request.
         if (!$rpc_client->send($mnet_host)) {
             $response = new StdClass();
             $response->status = MNET_FAILURE;
             $response->errors[] = implode('<br/>', $rpc_client->getErrors($mnet_host));
             if (debugging()) {
                 print_object($rpc_client);
             }
         } else {
             $response = json_decode($rpc_client->response);
         }
         // Recording response.
         $responses[$mnet_host->wwwroot] = $response;
     }
     // Saving results.
     $this->results = $responses + $this->results;
 }
/**
 * @param object $submitteddata
 *
 */
function vmoodle_bind_to_network($submitteddata, &$newmnet_host)
{
    global $USER, $CFG, $DB, $OUTPUT;
    // debug_trace("step 4.4 : binding to subnetwork");
    // Getting services schemes to apply
    // debug_trace("step 4.4.1 : getting services");
    vmoodle_get_service_strategy($submitteddata, $services, $peerservices, 'peer');
    // debug_trace("step 4.4.2 : getting possible peers");
    $idnewblock = $DB->get_field('local_vmoodle', 'id', array('vhostname' => $submitteddata->vhostname));
    // last mnet has been raised by one at step 3 so we add to network if less
    if ($submitteddata->mnet < vmoodle_get_last_subnetwork_number()) {
        // Retrieves the subnetwork member(s).
        $subnetwork_hosts = array();
        $select = 'id != ? AND mnet = ? AND enabled = 1';
        $subnetwork_members = $DB->get_records_select('local_vmoodle', $select, array($idnewblock, $submitteddata->mnet));
        if (!empty($subnetwork_members)) {
            // debug_trace("step 4.4.3 : preparing peers");
            foreach ($subnetwork_members as $subnetwork_member) {
                $temp_host = new stdClass();
                $temp_host->wwwroot = $subnetwork_member->vhostname;
                $temp_host->name = utf8_decode($subnetwork_member->name);
                $subnetwork_hosts[] = $temp_host;
            }
        }
        // Member(s) of the subnetwork add the new host.
        if (!empty($subnetwork_hosts)) {
            // debug_trace("step 4.4.4 : bind peers");
            $rpc_client = new \local_vmoodle\XmlRpc_Client();
            $rpc_client->reset_method();
            $rpc_client->set_method('local/vmoodle/rpclib.php/mnetadmin_rpc_bind_peer');
            // Authentication params.
            $rpc_client->add_param($USER->username, 'string');
            $userhostroot = $DB->get_field('mnet_host', 'wwwroot', array('id' => $USER->mnethostid));
            $rpc_client->add_param($userhostroot, 'string');
            $rpc_client->add_param($CFG->wwwroot, 'string');
            // Peer to bind to.
            $rpc_client->add_param((array) $newmnet_host, 'array');
            $rpc_client->add_param($peerservices, 'array');
            foreach ($subnetwork_hosts as $subnetwork_host) {
                // debug_trace("step 4.4.4.1 : bind to -> $subnetwork_host->wwwroot");
                $temp_member = new \local_vmoodle\Mnet_Peer();
                $temp_member->set_wwwroot($subnetwork_host->wwwroot);
                if (!$rpc_client->send($temp_member)) {
                    echo $OUTPUT->notification(implode('<br />', $rpc_client->getErrors($temp_member)));
                    if (debugging()) {
                        echo '<pre>';
                        // var_dump($rpc_client);
                        echo '</pre>';
                    }
                }
                // debug_trace("step 4.4.4.1 : bind from <- $subnetwork_host->wwwroot");
                $rpc_client_2 = new \local_vmoodle\XmlRpc_Client();
                $rpc_client_2->reset_method();
                $rpc_client_2->set_method('local/vmoodle/rpclib.php/mnetadmin_rpc_bind_peer');
                // Authentication params.
                $rpc_client_2->add_param($USER->username, 'string');
                $userhostroot = $DB->get_field('mnet_host', 'wwwroot', array('id' => $USER->mnethostid));
                $rpc_client_2->add_param($userhostroot, 'string');
                $rpc_client_2->add_param($CFG->wwwroot, 'string');
                // Peer to bind to.
                $rpc_client_2->add_param((array) $temp_member, 'array');
                $rpc_client_2->add_param($services, 'array');
                if (!$rpc_client_2->send($newmnet_host)) {
                    echo $OUTPUT->notification(implode('<br />', $rpc_client_2->getErrors($newmnet_host)));
                    if (debugging()) {
                        echo '<pre>';
                        // var_dump($rpc_client_2);
                        echo '</pre>';
                    }
                }
                unset($rpc_client_2);
                // free some resource
            }
        }
    }
    // Getting services schemes to apply to main
    // debug_trace("step 4.4.5 : getting services");
    vmoodle_get_service_strategy($submitteddata, $services, $peerservices, 'main');
    // debug_trace("step 4.4.5.1 : bind to -> $CFG->wwwroot");
    $mainhost = new \local_vmoodle\Mnet_Peer();
    // this is us
    $mainhost->set_wwwroot($CFG->wwwroot);
    // debug_trace('step 4.4.5.2 : Binding our main service strategy to remote');
    // bind the local service strategy to new host
    if (!empty($peerservices)) {
        $DB->delete_records('mnet_host2service', array('hostid' => $newmnet_host->id));
        // eventually deletes something on the way
        foreach ($peerservices as $servicename => $servicestate) {
            $service = $DB->get_record('mnet_service', array('name' => $servicename));
            $host2service = new stdclass();
            $host2service->hostid = $newmnet_host->id;
            $host2service->serviceid = $service->id;
            $host2service->publish = 0 + @$servicestate->publish;
            $host2service->subscribe = 0 + @$servicestate->subscribe;
            $DB->insert_record('mnet_host2service', $host2service);
            // debug_trace("step 4.4.5.2 : adding ".serialize($host2service));
        }
    }
    // debug_trace('step 4.4.5.4 : Binding remote service strategy to main');
    $rpc_client = new \local_vmoodle\XmlRpc_Client();
    $rpc_client->reset_method();
    $rpc_client->set_method('local/vmoodle/rpclib.php/mnetadmin_rpc_bind_peer');
    $rpc_client->add_param($USER->username, 'string');
    $userhostroot = $DB->get_field('mnet_host', 'wwwroot', array('id' => $USER->mnethostid));
    $rpc_client->add_param($userhostroot, 'string');
    $rpc_client->add_param($CFG->wwwroot, 'string');
    // Peer to bind to : this is us.
    $rpc_client->add_param((array) $mainhost, 'array');
    $rpc_client->add_param($services, 'array');
    // debug_trace('step 4.4.5.4 : Sending');
    if (!$rpc_client->send($newmnet_host)) {
        // echo $OUTPUT->notification(implode('<br />', $rpc_client->getErrors($newmnet_host)));
        if (debugging()) {
            echo '<pre>';
            // var_dump($rpc_client);
            echo '</pre>';
        }
    }
}
 /**
  * Execute the command.
  * @param    $hosts        mixed            The host where run the command (may be wwwroot or an array).
  * @throws                Command_Exception.
  */
 public function run($hosts)
 {
     global $CFG, $USER;
     // Adding constants.
     require_once $CFG->dirroot . '/local/vmoodle/rpclib.php';
     // Checking capability to run.
     if (!has_capability('local/vmoodle:execute', \context_system::instance())) {
         throw new Command_Exception('insuffisantcapabilities');
     }
     // Getting plugin.
     list($type, $plugin) = explode('/', $this->getParameter('plugin')->getValue());
     // Getting the state.
     $state = $this->getParameter('state')->getValue();
     $pm = \plugin_manager::instance();
     $plugininfo = $pm->get_plugin_info($plugin);
     if (empty($plugininfo->type)) {
         if (empty($plugininfo)) {
             $plugininfo = new \StdClass();
         }
         $plugininfo->type = $type;
     }
     $plugininfo->action = $state;
     $plugininfos[$plugin] = (array) $plugininfo;
     // Creating XMLRPC client to change remote configuration.
     $rpc_client = new \local_vmoodle\XmlRpc_Client();
     $rpc_client->set_method('local/vmoodle/plugins/plugins/rpclib.php/mnetadmin_rpc_set_plugins_states');
     $rpc_client->add_param($plugininfos, 'array');
     // Initializing responses.
     $responses = array();
     // Creating peers.
     $mnet_hosts = array();
     if (!empty($hosts)) {
         foreach ($hosts as $host => $name) {
             $mnet_host = new \mnet_peer();
             if ($mnet_host->bootstrap($host, null, 'moodle')) {
                 $mnet_hosts[] = $mnet_host;
             } else {
                 $responses[$host] = (object) array('status' => MNET_FAILURE, 'error' => get_string('couldnotcreateclient', 'local_vmoodle', $host));
             }
         }
     }
     // Sending requests.
     foreach ($mnet_hosts as $mnet_host) {
         // Sending request.
         if (!$rpc_client->send($mnet_host)) {
             $response = new \StdClass();
             $response->status = MNET_FAILURE;
             $response->errors[] = implode('<br/>', $rpc_client->getErrors($mnet_host));
             if (debugging()) {
                 echo '<pre>';
                 var_dump($rpc_client);
                 echo '</pre>';
             }
         } else {
             $response = json_decode($rpc_client->response);
         }
         // Recording response.
         $responses[$mnet_host->wwwroot] = $response;
         // Recording plugin descriptors.
         if ($response->status == RPC_SUCCESS) {
             $this->plugins[$mnet_host->wwwroot] = @$response->value;
         }
     }
     // Saving results
     $this->results = $responses + $this->results;
 }
 /**
  * Execute the command.
  * @param mixed $hosts The host where run the command (may be wwwroot or an array).
  * @throws Command_Exception
  */
 function run($hosts)
 {
     global $CFG, $USER;
     // Adding constants.
     require_once $CFG->dirroot . '/local/vmoodle/rpclib.php';
     // Checking capabilities.
     if (!has_capability('local/vmoodle:execute', context_system::instance())) {
         throw new Command_Exception('insuffisantcapabilities');
     }
     // Getting plugintype.
     $plugintype = $this->getParameter('plugintype')->getValue();
     // Checking hosts.
     $platform = $this->getParameter('platform')->getValue();
     if (array_key_exists($platform, $hosts)) {
         $platforms = get_available_platforms();
         throw new Command_Plugins_Exception('syncwithitself');
     }
     // Creating peer to read plugins configuration from the designated peer.
     $mnet_host = new mnet_peer();
     if (!$mnet_host->bootstrap($this->getParameter('platform')->getValue(), null, 'moodle')) {
         $response = (object) array('status' => MNET_FAILURE, 'error' => get_string('couldnotcreateclient', 'local_vmoodle', $platform));
         // if we fail, we fail for all.
         foreach ($hosts as $host => $name) {
             $this->results[$host] = $response;
         }
         return;
     }
     // Creating XMLRPC client to read plugins configuration.
     $rpc_client = new \local_vmoodle\XmlRpc_Client();
     $rpc_client->set_method('local/vmoodle/plugins/plugins/rpclib.php/mnetadmin_rpc_get_plugins_info');
     $rpc_client->add_param($plugintype, 'string');
     // Checking result.
     if (!($rpc_client->send($mnet_host) && ($response = json_decode($rpc_client->response)) && $response->status == RPC_SUCCESS)) {
         // Creating response.
         if (!isset($response)) {
             $response = new Stdclass();
             $response->status = MNET_FAILURE;
             $response->errors[] = implode('<br/>', $rpc_client->getErrors($mnet_host));
             $response->error = implode('<br/>', $rpc_client->getErrors($mnet_host));
         }
         if (debugging()) {
             echo '<pre>';
             var_dump($rpc_client);
             ob_flush();
             echo '</pre>';
         }
         // result is a plugin info structure that needs be replicated remotely to all targets.
         $plugininfos = $response->value;
         return;
     }
     // Initializing responses.
     $responses = array();
     // Creating peers
     $mnet_hosts = array();
     foreach ($hosts as $host => $name) {
         $mnet_host = new mnet_peer();
         if ($mnet_host->bootstrap($host, null, 'moodle')) {
             $mnet_hosts[] = $mnet_host;
         } else {
             $responses[$host] = (object) array('status' => MNET_FAILURE, 'error' => get_string('couldnotcreateclient', 'local_vmoodle', $host));
         }
     }
     // Creating XMLRPC client
     $rpc_client = new \local_vmoodle\XmlRpc_Client();
     $rpc_client->set_method('local/vmoodle/plugins/plugins/rpclib.php/mnetadmin_rpc_set_plugins_states');
     $rpc_client->add_param($plugininfos, 'object');
     // plugininfos structure
     // Sending requests.
     foreach ($mnet_hosts as $mnet_host) {
         // Sending request
         if (!$rpc_client->send($mnet_host)) {
             $response = new Stdclass();
             $response->status = MNET_FAILURE;
             $response->errors[] = implode('<br/>', $rpc_client->getErrors($mnet_host));
             $response->error = 'Set plugin state failed : Remote call error';
             if (debugging()) {
                 echo '<pre>';
                 var_dump($rpc_client);
                 ob_flush();
                 echo '</pre>';
             }
         } else {
             $response = json_decode($rpc_client->response);
         }
         // Recording response.
         $responses[$mnet_host->wwwroot] = $response;
     }
     // Saving results.
     $this->results = $responses + $this->results;
 }
 /**
  * Execute the command.
  * @param mixed $host The hosts where run the command (may be wwwroot or an array).
  * @throws Command_SetConfig_Exception
  */
 public function run($hosts)
 {
     global $CFG, $USER;
     // Adding constants.
     require_once $CFG->dirroot . '/local/vmoodle/rpclib.php';
     // Checking host.
     if (!is_array($hosts)) {
         $hosts = array($hosts => 'Unnamed host');
     }
     // Checking capabilities.
     if (!has_capability('local/vmoodle:execute', \context_system::instance())) {
         throw new Command_SetConfig_Exception('insuffisantcapabilities');
     }
     // Initializing responses.
     $responses = array();
     // Creating peers.
     $mnet_hosts = array();
     foreach ($hosts as $host => $name) {
         $mnet_host = new \mnet_peer();
         if ($mnet_host->bootstrap($host, null, 'moodle')) {
             $mnet_hosts[] = $mnet_host;
         } else {
             $responses[$host] = (object) array('status' => MNET_FAILURE, 'error' => get_string('couldnotcreateclient', 'local_vmoodle', $host));
         }
     }
     // Getting command.
     $command = $this->isReturned();
     // Creating XMLRPC client.
     $rpc_client = new \local_vmoodle\XmlRpc_Client();
     $rpc_client->set_method('local/vmoodle/plugins/generic/rpclib.php/mnetadmin_rpc_set_config');
     $pluginkey = $this->getParameter('key')->getValue();
     $parts = explode('/', $pluginkey);
     $key = array_pop($parts);
     // take last as key
     $plugin = implode('/', $parts);
     // take the rest as plugin (minds those plugins as auth/cas or auth/ldap)
     $rpc_client->add_param($key, 'string');
     $rpc_client->add_param($this->getParameter('value')->getValue(), 'string');
     $rpc_client->add_param($plugin, 'string');
     $rpc_client->add_param($command, 'boolean');
     // Sending requests.
     foreach ($mnet_hosts as $mnet_host) {
         // Sending request.
         if (!$rpc_client->send($mnet_host)) {
             $response = new StdClass();
             $response->status = MNET_FAILURE;
             $response->errors[] = implode('<br/>', $rpc_client->getErrors($mnet_host));
             if (debugging()) {
                 echo '<pre>';
                 var_dump($rpc_client);
                 echo '</pre>';
             }
         } else {
             $response = json_decode($rpc_client->response);
         }
         // Recording response.
         $responses[$mnet_host->wwwroot] = $response;
     }
     // Saving results.
     $this->results = $responses + $this->results;
 }
/**
 * force user account creation.
 * @param object $callinguser The calling user.
 * @param string $targetuser The username of the user to be created.
 * @param array $userparams an array containing all data for user.
 * @param string $userhostname the user's origin account.
 * @param array $bounceto an array of or a string containing hostnames to propagate users to.
 * @param boolean $onlybounce if true, do not try to create the user locally, just bounce.
 *
 * if userhostname is empty, the user is created with an account bound to the localhost mnethost id (local account) and
 * reset to manual auth if the auth is 'mnet' (note the auth will remain unchanged if other than mnet, so it is possible to preset
 * an SAML or LDAP bound account.
 * If userhostname is not empty, the call forces auth being mnet, whatever the auth field was set to, and the hostname is searched
 * for a local matching host in mnet_hosts.
 *
 * If bounceto is not empty, the account will be propagated to matching mnet_hosts in the MNET proximity.
 * The onlybounce feature is provided for using this rpc function using a local direct call to propagate a user programatically
 * a user to some bounce locations
 */
function mnetadmin_rpc_create_user($callinguser, $targetuser, $userparams, $userhostname = '', $bounceto = null, $onlybounce = false, $json_response = true, $overridecapability = false)
{
    global $CFG, $USER, $DB;
    $response = new StdClass();
    $response->status = RPC_SUCCESS;
    $response->errors = array();
    $response->error = '';
    $userparamsarr = (array) $userparams;
    $capability = '';
    if (!$overridecapability) {
        $capability = 'local/vmoodle:execute';
    }
    if ($auth_response = invoke_local_user((array) $callinguser, $capability)) {
        if ($json_response) {
            return $auth_response;
        } else {
            return json_decode($auth_response);
        }
    }
    // be sure of our structure type.
    $callinguser = (object) $callinguser;
    if (!$onlybounce) {
        if (function_exists('debug_trace')) {
            debug_trace("Up to create {$targetuser} ");
        }
        if (!($user = $DB->get_record('user', array('username' => $targetuser)))) {
            // Collect eventual profilefields and cleanup user record from them.
            foreach ($userparamsarr as $key => $value) {
                if (preg_match('/^profile_field_/', $key)) {
                    $profilefields[$key] = $value;
                    unset($userparams[$key]);
                }
            }
            if (function_exists('debug_trace')) {
                debug_trace("Making new user record");
            }
            $newuser = (object) $userparams;
            $newuser->username = $targetuser;
            // Remap local mnethostid and auth method if needed.
            if (!empty($userhostname)) {
                if (!($originuserhost = $DB->get_record('mnet_host', array('wwwroot' => $userhostname)))) {
                    // If we fail to find real origin host for the user, take request host as failover.
                    if (function_exists('debug_trace')) {
                        debug_trace("REMOTE CALL ERROR : Bad origin host. Trying {$callinguser->remotehostroot} as failover");
                    }
                    if (!($originuserhost = $DB->get_record('mnet_host', array('wwwroot' => $callinguser->remotehostroot)))) {
                        if (function_exists('debug_trace')) {
                            debug_trace("REMOTE CALL ERROR : Bad origin host " . json_encode($userhostname));
                        }
                        $response = new StdClass();
                        $response->status = 510;
                        $response->errors[] = "Bad origin host " . json_encode($userhostname) . ", or origin host of the user is not known by this host.";
                        $response->error = "Bad origin host " . json_encode($userhostname) . ", or origin host of the user is not known by this host.";
                        if ($json_response) {
                            return json_encode($response);
                        } else {
                            return $response;
                        }
                    }
                }
                $newuser->mnethostid = $originuserhost->id;
                if ($originuserhost->id != $CFG->mnet_localhost_id && (empty($newuser->auth) || $newuser->auth == 'manual')) {
                    $newuser->auth = 'mnet';
                } else {
                    if (empty($newuser->auth) || $newuser->auth == 'mnet') {
                        $newuser->auth = 'manual';
                    }
                }
            } else {
                $newuser->mnethostid = $CFG->mnet_localhost_id;
                if (empty($newuser->auth) || $newuser->auth == 'mnet') {
                    $newuser->auth = 'manual';
                }
            }
            $newuser->confirmed = 1;
            $newuser->timemodified = time();
            if (function_exists('debug_trace')) {
                debug_trace("REMOTE CALL : recording user");
            }
            if (!($userid = $DB->insert_record('user', $newuser))) {
                if (function_exists('debug_trace')) {
                    debug_trace("REMOTE CALL ERROR : User creation failure");
                }
                $response->status = RPC_FAILURE_RECORD;
                $response->errors[] = "Could not create the user.";
                $response->error = "Could not create the user.";
                if ($json_response) {
                    return json_encode($response);
                } else {
                    return $response;
                }
            }
            $response->userid = $userid;
            // add profilefields
            if (function_exists('debug_trace')) {
                debug_trace("REMOTE CALL : Adding profile fields");
            }
            if (!empty($profilefields)) {
                foreach ($profilefields as $key => $value) {
                    $key = str_replace('profile_field_', '', $key);
                    // extract real shortname
                    if ($field = $DB->get_record('user_info_field', array('shortname' => $key))) {
                        // Do insert only if known field. Ignore others.
                        $valuerec->userid = $userid;
                        $valuerec->fieldid = $field->id;
                        $valuerec->data = $value;
                        $DB->insert_record('user_info_data', $valuerec);
                    }
                }
            }
        } else {
            if (function_exists('debug_trace')) {
                debug_trace("REMOTE CALL : Reviving user");
            }
            if ($user->deleted == 1) {
                $user->deleted = 0;
                foreach ($userparams as $key => $value) {
                    $user->{$key} = $value;
                }
                $user->username = $targetuser;
                if (!($userid = $DB->update_record('user', $user))) {
                    if (function_exists('debug_trace')) {
                        debug_trace("REMOTE CALL ERROR : User revival failure");
                    }
                    $response->status = RPC_FAILURE_RECORD;
                    $response->errors[] = "Create user REMOTE CALL : Could not revive the user.";
                    $response->error = "Create user REMOTE CALL : Could not revive the user.";
                    if ($json_response) {
                        return json_encode($response);
                    } else {
                        return $response;
                    }
                }
                $response->userid = $userid;
            } else {
                if (function_exists('debug_trace')) {
                    debug_trace("Create user REMOTE CALL : User exists");
                }
                /*
                // usually create user matching user should be happy with that
                $response->status = RPC_SUCCESS;
                $response->errors[] = "User already exists.";
                $response->error = "User already exists.";
                if ($json_response) {
                    return json_encode($response);
                } else {
                    return $response;
                }
                */
            }
        }
    } else {
        if (!($userparams = $DB->get_record('user', array('username' => $targetuser)))) {
            $response->status = RPC_FAILURE_RECORD;
            $response->errors[] = "Create user REMOTE CALL : No such user to propagate.";
            $response->error = "Create user REMOTE CALL : No such user to propagate.";
            if ($json_response) {
                return json_encode($response);
            } else {
                return $response;
            }
        }
        if (function_exists('debug_trace')) {
            debug_trace('Create user REMOTE CALL : got user data as ' . json_encode($userparams));
        }
    }
    // Now proceed to bounces if any.
    if (!empty($bounceto)) {
        if (is_string($bounceto)) {
            $bounceto = explode(';', $bounceto);
        }
        foreach ($bounceto as $bouncehost) {
            // Check if known as mnet_hosts and possible to send admin requests.
            $sql = "\n                SELECT\n                    COUNT(*)\n                FROM \n                    {mnet_host} as mh,\n                    {mnet_service} as ms,\n                    {mnet_host2service} as h2s\n                WHERE\n                    mh.wwwroot = '{$bouncehost}' AND\n                    mh.id = h2s.hostid AND\n                    mh.deleted = 0 AND\n                    h2s.serviceid = ms.id AND\n                    ms.name = 'mnetadmin' AND\n                    h2s.subscribe = 1\n            ";
            $ok = $DB->count_records_sql($sql);
            if ($ok) {
                // We can do it.
                $userhostroot = $DB->get_field('mnet_host', 'wwwroot', array('id' => $USER->mnethostid));
                $rpc_client = new \local_vmoodle\XmlRpc_Client();
                $rpc_client->reset_method();
                $rpc_client->set_method('local/vmoodle/plugins/roles/rpclib.php/mnetadmin_rpc_create_user');
                $caller = new StdClass();
                $caller->username = $USER->username;
                $caller->remoteuserhostroot = $userhostroot;
                $caller->remotehostroot = $CFG->wwwroot;
                $rpc_client->add_param($caller, 'struct');
                // username
                $rpc_client->add_param($targetuser, 'string');
                $rpc_client->add_param($userparams, 'struct');
                if ($userhostname == '') {
                    $rpc_client->add_param($CFG->wwwroot, 'string');
                } else {
                    $rpc_client->add_param($userhostname, 'string');
                }
                if (function_exists('debug_trace')) {
                    debug_trace("REMOTE CALL : Bouncing to {$bouncehost} ");
                }
                $mnet_host = new mnet_peer();
                if ($mnet_host->set_wwwroot($bouncehost)) {
                    $result = $rpc_client->send($mnet_host);
                    if (empty($result)) {
                        // if (preg_match('/dev/', $CFG->wwwroot)) print_object($rpc_client);
                        $response->errors[] = 'Create user : bounce failed rpc transaction to ' . $bouncehost;
                        $response->errors[] = $rpc_client->getErrors();
                        $response->error = 'Create user : bounce failed rpc transaction to ' . $bouncehost;
                    } else {
                        // whatever we have, aggregate eventual remote errors to error stack.
                        $res = json_decode($rpc_client->response);
                        if (!empty($res->errors)) {
                            foreach ($res->errors as $remoteerror) {
                                $response->errors[] = 'REMOTE: ' . implode(' ', (array) $remoteerror);
                                $response->error = 'REMOTE : bounce failed rpc some of transactions to ' . $bouncehost;
                            }
                        }
                    }
                } else {
                    // silently ignore unless debugging
                    if (function_exists('debug_trace')) {
                        debug_trace("Bounce ignored  : No service capability for {$bouncehost} ");
                    }
                    $response->errors[] = 'Create user : ignoring bounce to ' . $bouncehost . ' because host communication failed.';
                    $response->error = 'Create user : (last error) ignoring bounce to ' . $bouncehost . ' because host communication failed.';
                }
            } else {
                $response->errors[] = 'Create user : ignoring bounce to ' . $bouncehost . ' because host unregistered.';
                $response->error = 'Create user : (last error) ignoring bounce to ' . $bouncehost . ' because host unregistered.';
            }
        }
    }
    if ($json_response) {
        return json_encode($response);
    } else {
        return $response;
    }
}