distributor.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <?php
  2. /**
  3. * Defines a class for viewing the SLOODLE Distributor module in Moodle.
  4. * Derived from the module view base class.
  5. *
  6. * @package sloodle
  7. * @copyright Copyright (c) 2008 Sloodle (various contributors)
  8. * @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3
  9. *
  10. * @contributor Peter R. Bloomfield
  11. * @contributor Edmund Edgar
  12. */
  13. /** The base module view class */
  14. require_once(SLOODLE_DIRROOT.'/view/base/base_view_module.php');
  15. define('SLOODLE_CHANNEL_DISTRIBUTOR_REQUEST_GIVE_OBJECT', 1639271151); // start the process to give the object
  16. /**
  17. * Class for rendering a view of a Distributor module in Moodle.
  18. * @package sloodle
  19. */
  20. class sloodle_view_distributor extends sloodle_base_view_module
  21. {
  22. /**
  23. * SLOODLE data about a Distributor, retrieved directly from the database (table: sloodle_distributor)
  24. * @var object
  25. * @access private
  26. */
  27. var $distributor = false;
  28. /**
  29. * Constructor.
  30. */
  31. function sloodle_base_view_module()
  32. {
  33. }
  34. /**
  35. * Processes request data to determine which Distributor is being accessed.
  36. */
  37. function process_request()
  38. {
  39. // Process the basic data
  40. parent::process_request();
  41. // Grab the Distributor data
  42. if (!$this->distributor = sloodle_get_record('sloodle_distributor', 'sloodleid', $this->sloodle->id)) error('Failed to get SLOODLE Distributor data.');
  43. }
  44. /**
  45. * Process any form data which has been submitted.
  46. */
  47. function process_form()
  48. {
  49. }
  50. /**
  51. * Render the view of the Distributor.
  52. */
  53. function render()
  54. {
  55. global $CFG, $USER;
  56. /*
  57. The version 1 method (distributor-1.0) uses a single XML-RPC channel.
  58. Presumably if you have multiple ones the most recent to update will win.
  59. Version 2 (distributor-2.0) uses the HTTP-in address that objects should already have.
  60. There may be more than one.
  61. We'll try to use the new method first, and if that fails fall back on the old one.
  62. */
  63. $id = required_param('id', PARAM_INT);
  64. $capableobjects = SloodleActiveObject::ObjectsCapableOfTaskActiveSince( 'distributor_send_object_http_in', time()-3600, array('sloodlemoduleid'=>$id) );
  65. // Fetch a list of all distributor entries
  66. $entries = sloodle_get_records('sloodle_distributor_entry', 'distributorid', $this->distributor->id, 'name');
  67. // If the query failed, then assume there were simply no items available
  68. if (!is_array($entries)) $entries = array();
  69. $numitems = count($entries);
  70. // A particular default user can be requested (by avatar name) in the HTTP parameters.
  71. // This could be used with a "send to this avatar" button on a Sloodle user profile.
  72. $defaultavatar = optional_param('defaultavatar', null, PARAM_TEXT);
  73. // // SEND OBJECT // //
  74. // If the user and object parameters are set, then try to send an object
  75. if (isset($_REQUEST['user'])) $send_user = $_REQUEST['user'];
  76. if (isset($_REQUEST['object'])) $send_object = $_REQUEST['object'];
  77. if (!empty($send_user) && !empty($send_object)) {
  78. // Convert the HTML entities back again
  79. $send_object = htmlentities(stripslashes($send_object));
  80. $errors = array();
  81. $ok = false;
  82. if (count($capableobjects) > 0) {
  83. foreach($capableobjects as $obj) {
  84. $v2message = new SloodleResponse();
  85. $v2message->set_status_code(SLOODLE_CHANNEL_DISTRIBUTOR_REQUEST_GIVE_OBJECT);
  86. $v2message->set_status_descriptor('INVENTORY');
  87. $v2message->set_request_descriptor('GIVE_INVENTORY');
  88. $v2message->set_http_in_password($obj->httpinpassword);
  89. $v2message->set_expect_response(1);
  90. $v2message->add_data_line($send_user);
  91. $v2message->add_data_line($send_object);
  92. $v2RenderStr="";
  93. $v2message->render_to_string($v2renderStr);
  94. //print $v2renderStr;
  95. $response = $obj->sendMessage($v2renderStr);
  96. if ($response['info']['http_code'] == 200) {
  97. // If we succeed on one, don't bother telling the user that we failed on others.
  98. if (isset($errors['messagesendingfailed'])) {
  99. unset($errors['messagesendingfailed']);
  100. }
  101. $responselines = explode("\n",$response['result']);
  102. $statusline = array_shift($responselines);
  103. if ($statusline > 0) {
  104. $ok = true;
  105. break;
  106. } else {
  107. // Other lines should be errors.
  108. // We'll ignore anything we don't understand.
  109. foreach($responselines as $line) {
  110. if (in_array($line, array('sloodleobjectnotfound', 'sloodleavatarnotfound'))) {
  111. $errors['sloodleobjectdistributor:'.$line] = true;
  112. }
  113. }
  114. }
  115. } else {
  116. $errors['messagesendingfailed'] = true;
  117. }
  118. }
  119. }
  120. if (!$ok && ( $this->distributor->channel != '' )) {
  121. // Construct and send the request
  122. $request = "1|OK\\nSENDOBJECT|$send_user|$send_object";
  123. $ok = sloodle_send_xmlrpc_message($this->distributor->channel, 0, $request);
  124. }
  125. // What was the result?
  126. sloodle_print_box_start('generalbox boxaligncenter boxwidthnarrow centerpara');
  127. if ($ok) {
  128. print '<h3 style="color:green;text-align:center;">'.get_string('sloodleobjectdistributor:successful','sloodle').'</h3>';
  129. } else {
  130. print '<h3 style="color:red;text-align:center;">'.get_string('sloodleobjectdistributor:failed','sloodle').'</h3>';
  131. }
  132. print '<p style="text-align:center;">';
  133. print get_string('Object','sloodle').': '.$send_object.'<br/>';
  134. print get_string('uuid','sloodle').': '.$send_user.'<br/>';
  135. //print get_string('xmlrpc:channel','sloodle').': '.$this->distributor->channel.'<br/>';
  136. print '</p>';
  137. sloodle_print_box_end();
  138. }
  139. // // ----------- // //
  140. // If there are no items in the distributor, then simply display an error message
  141. if ($numitems < 1) sloodle_print_box('<span style="font-weight:bold; color:red;">'.get_string('sloodleobjectdistributor:noobjects','sloodle').'</span>', 'generalbox boxaligncenter boxwidthnormal centerpara');
  142. //error(get_string('sloodleobjectdistributor:noobjects','sloodle'));
  143. // If there is no XMLRPC channel specified, then display a warning message
  144. $disabledattr = '';
  145. if ( empty($this->distributor->channel) && (count($capableobjects) == 0) ) {
  146. sloodle_print_box('<span style="font-weight:bold; color:red;">'.get_string('sloodleobjectdistributor:nochannel','sloodle').'</span>', 'generalbox boxaligncenter boxwidthnormal centerpara');
  147. $disabledattr = 'disabled="true"';
  148. }
  149. // Construct the selection box of items
  150. $selection_items = '<select name="object" size="1">';
  151. foreach ($entries as $e) {
  152. $escapedname = stripslashes($e->name);
  153. $selection_items .= "<option value=\"{$e->name}\">{$escapedname}</option>\n";
  154. }
  155. $selection_items .= '</select>';
  156. // Get a list of all avatars on the site
  157. $avatars = sloodle_get_records('sloodle_users', '', '', 'avname');
  158. if (!$avatars) $avatars = array();
  159. // Construct the selection box of avatars
  160. $selection_avatars = '<select name="user" size="1">';
  161. foreach ($avatars as $a) {
  162. // Skip avatars who do not have a UUID or associated Moodle account
  163. if (empty($a->uuid) || empty($a->userid)) continue;
  164. // Make sure the associated Moodle user can view the current course
  165. if (!has_capability('mod/sloodle:courseparticipate', $this->course_context, $a->userid)) continue;
  166. $sel = '';
  167. if ($a->avname == $defaultavatar) $sel = 'selected="true"';
  168. $selection_avatars .= "<option value=\"{$a->uuid}\" $sel>{$a->avname}</option>\n";
  169. }
  170. $selection_avatars .= '</select>';
  171. // There will be 3 forms:
  172. // - send to self
  173. // - send to another avatar on the course
  174. // - send to custom UUID
  175. // The first 1 will be available to any registered user whose avatar is in the database.
  176. // The other 2 will only be available to those with the activity management capability.
  177. // Furthermore, the 2nd form will only be available if there is at least 1 avatar registered on the site.
  178. // Start of the sending forms
  179. sloodle_print_box_start('generalbox boxaligncenter boxwidthnormal centerpara');
  180. // // SEND TO SELF // //
  181. // Start the form
  182. echo '<form action="" method="POST">';
  183. // Use a table for layout
  184. $table_sendtoself = new stdClass();
  185. $table_sendtoself->head = array(get_string('sloodleobjectdistributor:sendtomyavatar','sloodle'));
  186. $table_sendtoself->align = array('center');
  187. // Fetch the current user's Sloodle info
  188. $this->sloodleuser = sloodle_get_record('sloodle_users', 'userid', $USER->id);
  189. if (!$this->sloodleuser) {
  190. $table_sendtoself->data[] = array('<span style="color:red;">'.get_string('avatarnotlinked','sloodle').'</span>');
  191. } else {
  192. // Output the hidden form data
  193. echo <<<XXXEODXXX
  194. <input type="hidden" name="s" value="{$this->sloodle->id}">
  195. <input type="hidden" name="user" value="{$this->sloodleuser->uuid}">
  196. XXXEODXXX;
  197. // Object selection box
  198. $table_sendtoself->data[] = array(get_string('selectobject','sloodle').': '.$selection_items);
  199. // Submit button
  200. $table_sendtoself->data[] = array('<input type="submit" '.$disabledattr.' value="'.get_string('sloodleobjectdistributor:sendtomyavatar','sloodle').' ('.$this->sloodleuser->avname.')" />');
  201. }
  202. // Print the table
  203. sloodle_print_table($table_sendtoself);
  204. // End the form
  205. echo "</form>";
  206. // Only show the other options if the user has permission to edit stuff
  207. if ($this->canedit) {
  208. // // SEND TO ANOTHER AVATAR // //
  209. // Start the form
  210. echo '<br><form action="" method="POST">';
  211. // Use a table for layout
  212. $table = new stdClass();
  213. $table->head = array(get_string('sloodleobjectdistributor:sendtoanotheravatar','sloodle'));
  214. $table->align = array('center');
  215. // Do we have any avatars?
  216. if (count($avatars) < 1) {
  217. $table->data[] = array('<span style="color:red;">'.get_string('nosloodleusers','sloodle').'</span>');
  218. } else {
  219. // Output the hidden form data
  220. echo <<<XXXEODXXX
  221. <input type="hidden" name="s" value="{$this->sloodle->id}">
  222. XXXEODXXX;
  223. // Avatar selection box
  224. $table->data[] = array(get_string('selectuser','sloodle').': '.$selection_avatars);
  225. // Object selection box
  226. $table->data[] = array(get_string('selectobject','sloodle').': '.$selection_items);
  227. // Submit button
  228. $table->data[] = array('<input type="submit" '.$disabledattr.' value="'.get_string('sloodleobjectdistributor:sendtoanotheravatar','sloodle').'" />');
  229. }
  230. // Print the table
  231. sloodle_print_table($table);
  232. // End the form
  233. echo "</form>";
  234. // // SEND TO A CUSTOM AVATAR // //
  235. // Start the form
  236. echo '<br><form action="" method="post">';
  237. // Use a table for layout
  238. $table = new stdClass();
  239. $table->head = array(get_string('sloodleobjectdistributor:sendtocustomavatar','sloodle'));
  240. $table->align = array('center');
  241. // Output the hidden form data
  242. echo <<<XXXEODXXX
  243. <input type="hidden" name="s" value="{$this->sloodle->id}">
  244. XXXEODXXX;
  245. // UUID box
  246. $table->data[] = array(get_string('uuid','sloodle').': '.'<input type="text" name="user" size="46" maxlength="36" />');
  247. // Object selection box
  248. $table->data[] = array(get_string('selectobject','sloodle').': '.$selection_items);
  249. // Submit button
  250. $table->data[] = array('<input type="submit" '.$disabledattr.' value="'.get_string('sloodleobjectdistributor:sendtocustomavatar','sloodle').'" />');
  251. // Print the table
  252. sloodle_print_table($table);
  253. // End the form
  254. echo "</form>";
  255. // // ---------- // //
  256. }
  257. sloodle_print_box_end();
  258. }
  259. }
  260. ?>