presenter.php 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127
  1. <?php
  2. /**
  3. * Defines a class for viewing the SLOODLE Presenter module in Moodle.
  4. * Derived from the module view base class.
  5. *
  6. * @package sloodle
  7. * @copyright Copyright (c) 2008-9 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 Paul Preibisch
  12. */
  13. //
  14. // The mode of operation is defined by the "mode" HTTP parameter.
  15. // The available modes are as follows:
  16. //
  17. // - view = viewing the Presentation (default)
  18. // - edit = editing the Presentation
  19. // - editslide = editing a particular slide
  20. // - addslide = adding a new slide
  21. // - addfiles = uploading multiple slides
  22. // - moveslide = moving a slide (part of 'edit' mode)
  23. // - deleteslide = deleting a particular slide (user has confirmed) (part of 'edit' mode)
  24. // - confirmdeleteslide = asking user to confirm that they want to delete a slide (part of 'edit' mode)
  25. // - deletemultiple = deleting multiple slides (user has confirmed) (part of 'edit' mode)
  26. // - confirmdeletemultiple = asking user to confirm that they want to delete multiple slides (part of 'edit' mode)
  27. // - importslides = add new slides using an importer plugin
  28. // - compatibility = run a full compatibility check of a specified plugin
  29. //
  30. /** The base module view class */
  31. require_once(SLOODLE_DIRROOT.'/view/base/base_view_module.php');
  32. /** The SLOODLE Session data structures */
  33. require_once(SLOODLE_LIBROOT.'/sloodle_session.php');
  34. /** ID of the 'view' tab for the Presenter. */
  35. define('SLOODLE_PRESENTER_TAB_VIEW', 1);
  36. /** ID of the 'edit' tab for the Presenter */
  37. define('SLOODLE_PRESENTER_TAB_EDIT', 2);
  38. /** ID of the 'edit slide' tab for the Presenter */
  39. define('SLOODLE_PRESENTER_TAB_EDIT_SLIDE', 3);
  40. /** ID of the 'add slide' tab for the Presenter */
  41. define('SLOODLE_PRESENTER_TAB_ADD_SLIDE', 4);
  42. /** ID of the 'bulk upload' tab for the Presenter */
  43. define('SLOODLE_PRESENTER_TAB_ADD_FILES', 5);
  44. /** ID of the 'import slides' tab for the Presenter */
  45. define('SLOODLE_PRESENTER_TAB_IMPORT_SLIDES', 6);
  46. /**
  47. * Class for rendering a view of a Presenter module in Moodle.
  48. * @package sloodle
  49. */
  50. class sloodle_view_presenter extends sloodle_base_view_module
  51. {
  52. /**
  53. * A Presenter object (secondary table).
  54. * @var object
  55. * @access private
  56. */
  57. var $presenter = null;
  58. /**
  59. * Our current mode of access to the Presenter.
  60. * This can be 'view', 'edit', 'editslide', 'bulkupload', 'upload'.
  61. * NOTE: 'edit' mode is for the presentation as a whole (slide order), while 'editslide' shows the slide editing form.
  62. * @var string
  63. * @access private
  64. */
  65. var $presenter_mode = 'view';
  66. /**
  67. * ID of the entry we are moving.
  68. * @var int
  69. * @access private
  70. */
  71. var $movingentryid = 0;
  72. /**
  73. * A SLOODLE session object to give us access to plugins and other functionality.
  74. * @var SloodleSession
  75. * @access private
  76. */
  77. var $_session = null;
  78. /**
  79. * Stores an optional feedback string which we may pick up from session data.
  80. * @var string
  81. * @access private
  82. */
  83. var $feedback = '';
  84. /**
  85. * Constructor.
  86. */
  87. function sloodle_view_presenter()
  88. {
  89. }
  90. /**
  91. * Processes request data to determine which Presenter is being accessed.
  92. */
  93. function process_request()
  94. {
  95. // Process the basic data
  96. parent::process_request();
  97. // Grab any feedback left from a previous action
  98. if (!empty($_SESSION['sloodle_presenter_feedback'])) $this->feedback = $_SESSION['sloodle_presenter_feedback'];
  99. unset($_SESSION['sloodle_presenter_feedback']);
  100. // Construct a SLOODLE Session and load a module
  101. $this->_session = new SloodleSession(false);
  102. $this->presenter = new SloodleModulePresenter($this->_session);
  103. if (!$this->presenter->load($this->cm->id)) return false;
  104. $this->_session->module = $this->presenter;
  105. // Load available Presenter plugins
  106. if (!$this->_session->plugins->load_plugins('presenter')) {
  107. error('Failed to load Presenter plugins.');
  108. return false;
  109. }
  110. }
  111. /**
  112. * Process any form data which has been submitted.
  113. */
  114. function process_form()
  115. {
  116. global $CFG;
  117. // Slight hack to put this here. We need to have the permissions checked before we do this.
  118. // Default to view mode. Only allow other types if the user has sufficient permission
  119. if ($this->canedit) {
  120. $this->presenter_mode = optional_param('mode', 'view', PARAM_TEXT);
  121. } else {
  122. $this->presenter_mode = 'view';
  123. }
  124. // If we're in moving mode, then grab the entry ID
  125. if ($this->presenter_mode == 'moveslide') $this->movingentryid = (int)optional_param('entry', 0);
  126. // Make sure Moodle includes our JavaScript files if necessary
  127. if ($this->presenter_mode == 'edit' || $this->presenter_mode == 'addfiles') {
  128. sloodle_require_js($CFG->wwwroot .'/mod/sloodle/lib/jquery/jquery.js');
  129. sloodle_require_js($CFG->wwwroot .'/mod/sloodle/lib/jquery/jquery.uploadify.js');
  130. sloodle_require_js($CFG->wwwroot .'/mod/sloodle/lib/jquery/jquery.checkboxes.js');
  131. sloodle_require_js($CFG->wwwroot .'/mod/sloodle/lib/multiplefileupload/extra.js');
  132. sloodle_require_js($CFG->wwwroot .'/lib/filelib.php');
  133. }
  134. if ( $this->presenter_mode == 'addfiles') {
  135. sloodle_require_js($CFG->wwwroot .'/mod/sloodle/lib/js/presenter_addfiles.js"');
  136. }
  137. // Should we process any incoming editing commands?
  138. if ($this->canedit) {
  139. // We may want to redirect afterwards to prevent an argument showing up in the address bar
  140. $redirect = false;
  141. // Are we deleting a single slide?
  142. if ($this->presenter_mode == 'deleteslide') {
  143. // Make sure the session key is specified and valid
  144. if (required_param('sesskey') != sesskey()) {
  145. error('Invalid session key');
  146. exit();
  147. }
  148. // Determine what slide is to be deleted
  149. $entryid = (int)required_param('entry', PARAM_INT);
  150. // Get the requested slide from the presentation
  151. $entry = $this->presenter->get_slide($entryid);
  152. if ($entry) {
  153. // Delete the slide
  154. $this->presenter->delete_entry($entryid);
  155. // Set our feedback information, so the user knows it has been successful
  156. $_SESSION['sloodle_presenter_feedback'] = get_string('presenter:deletedslide', 'sloodle', $entry->name);
  157. } else {
  158. // Set our feedback information, so the user knows it has not been successful;
  159. $_SESSION['sloodle_presenter_feedback'] = get_string('presenter:deletedslides', 'sloodle', 0);
  160. }
  161. // Redirect back to the edit tab to get rid of our messy request parameters (and to prevent accidental repeat of the operation)
  162. $redirect = true;
  163. }
  164. // Are we deleting multiple slides?
  165. if ($this->presenter_mode == 'deletemultiple') {
  166. // Make sure the session key is specified and valid
  167. if (required_param('sesskey') != sesskey()) {
  168. error('Invalid session key');
  169. exit();
  170. }
  171. // Fetch the IDs of the slides which are being deleted
  172. if (isset($_REQUEST['entriesstr'])) $entryids = explode(',',$_REQUEST['entriesstr']);
  173. else error("Expected HTTP parameter 'entries' not found.");
  174. // Go through the given entry IDs and attempt to delete them
  175. $numdeleted = 0;
  176. foreach ($entryids as $entryid) {
  177. if ($this->presenter->delete_entry($entryid)) $numdeleted++;
  178. }
  179. // Set our feedback information so the user knows whether or not this was successful
  180. $_SESSION['sloodle_presenter_feedback'] = get_string('presenter:deletedslides', 'sloodle', $numdeleted);
  181. // Redirect back to the edit tab to get rid of our messy request parameters (and to prevent accidental repeat of the operation)
  182. $redirect = true;
  183. }
  184. // Are we relocating an entry?
  185. if ($this->presenter_mode == 'setslideposition') {
  186. $entryid = (int)required_param('entry', PARAM_INT);
  187. $position = (int)required_param('position', PARAM_INT);
  188. $this->presenter->relocate_entry($entryid, $position);
  189. $redirect = true;
  190. }
  191. // Has a new entry been added?
  192. if (isset($_REQUEST['fileaddentry']) ||isset($_REQUEST['sloodleaddentry'])) {
  193. if (isset($_REQUEST['fileaddentry'])) {
  194. $urls = $_REQUEST['fileurl'];
  195. $names = $_REQUEST['filename'];
  196. $i = 0;
  197. foreach ($urls as $u) {
  198. $fnamelen= strlen($u);
  199. $extension= substr($u,$fnamelen-4);
  200. $ftype = strtolower($extension);
  201. switch ($ftype){
  202. case ".mov": $ftype = "video"; break;
  203. case ".mp4": $ftype = "video"; break;
  204. case ".jpg": $ftype = "image"; break;
  205. case ".png": $ftype = "image"; break;
  206. case ".gif": $ftype = "image"; break;
  207. case ".bmp": $ftype = "image"; break;
  208. case ".htm": $ftype = "web"; break;
  209. case "html": $ftype = "web"; break;
  210. }
  211. $this->presenter->add_entry(sloodle_clean_for_db($u), $ftype, sloodle_clean_for_db($names[$i++]));
  212. }
  213. $redirect = true;
  214. }
  215. if (isset($_REQUEST['sloodleaddentry'])) {
  216. if ($_REQUEST['sloodleentryurl']!='') {
  217. $sloodleentryurl = sloodle_clean_for_db($_REQUEST['sloodleentryurl']);
  218. $sloodleentrytype = sloodle_clean_for_db($_REQUEST['sloodleentrytype']);
  219. $sloodleentryname = sloodle_clean_for_db($_REQUEST['sloodleentryname']);
  220. $sloodleentryposition = (int)$_REQUEST['sloodleentryposition'];
  221. // Store the type in session data for next time we're adding a slide
  222. $_SESSION['sloodle_presenter_add_type'] = $sloodleentrytype;
  223. $this->presenter->add_entry($sloodleentryurl, $sloodleentrytype, $sloodleentryname, $sloodleentryposition);
  224. }
  225. }
  226. $redirect = true;
  227. }
  228. // Has an existing entry been edited?
  229. if (isset($_REQUEST['sloodleeditentry'])) {
  230. $sloodleentryid = (int)$_REQUEST['sloodleentryid'];
  231. $sloodleentryurl = sloodle_clean_for_db($_REQUEST['sloodleentryurl']);
  232. $sloodleentrytype = sloodle_clean_for_db($_REQUEST['sloodleentrytype']);
  233. $sloodleentryname = sloodle_clean_for_db($_REQUEST['sloodleentryname']);
  234. $sloodleentryposition = (int)$_REQUEST['sloodleentryposition'];
  235. $this->presenter->edit_entry($sloodleentryid, $sloodleentryurl, $sloodleentrytype, $sloodleentryname, $sloodleentryposition);
  236. $redirect = true;
  237. }
  238. // Redirect back to the edit page -- this is used to get rid of intermediate parameters.
  239. if ($redirect && headers_sent() == false) {
  240. header("Location: ".SLOODLE_WWWROOT."/view.php?id={$this->cm->id}&mode=edit");
  241. exit();
  242. }
  243. }
  244. }
  245. /**
  246. * Render the View of the Presenter.
  247. * Called from with the {@link render()} function when necessary.
  248. */
  249. function render_view()
  250. {
  251. //display any feedback
  252. if (!empty($this->feedback)) echo $this->feedback;
  253. // Get a list of entry slides in this presenter
  254. $entries = $this->presenter->get_slides();
  255. if (!is_array($entries)) $entries = array();
  256. $numentries = count($entries);
  257. // Open the presentation box
  258. //sloodle_print_box_start('generalbox boxaligncenter boxwidthwide');
  259. // Was a specific entry requested? This is the number of entry within the presentation, NOT entry ID.
  260. // They start at 1 and go up from there within each presentation.
  261. if (isset($_REQUEST['sloodledisplayentry'])) {
  262. $displayentrynum = (int)$_REQUEST['sloodledisplayentry'];
  263. if ($displayentrynum < 1 || $displayentrynum > $numentries) $displayentrynum = 1;
  264. } else {
  265. $displayentrynum = 1;
  266. }
  267. // Do we have any entries to work with?
  268. if ($numentries > 0) {
  269. // Yes - go through them to figure out which entry to display
  270. $currententry = null;
  271. foreach ($entries as $entryid => $entry) {
  272. // Check if this is our current entry
  273. if ($displayentrynum == $entry->slideposition) {
  274. $currententry = $entry;
  275. }
  276. }
  277. // Display the entry header
  278. echo "<div style=\"text-align:center;\">";
  279. echo "<h2 id=\"slide\">\"<a href=\"{$currententry->source}\" title=\"".get_string('directlink', 'sloodle')."\">{$currententry->name}</a>\"</h2>\n";
  280. // Display the presentation controls
  281. $strof = get_string('of', 'sloodle');
  282. $strviewprev = get_string('viewprev', 'sloodle');
  283. $strviewnext = get_string('viewnext', 'sloodle');
  284. $strviewjumpforward = get_string('jumpforward', 'sloodle');
  285. $strviewjumpback = get_string('jumpback', 'sloodle');
  286. echo '<p style="font-size:200%; font-weight:bold;">';
  287. // if ($displayentrynum > 1) echo "<a href=\"?id={$this->cm->id}&sloodledisplayentry=",$displayentrynum - 1,"#slide\" title=\"{$strviewprev}\">&larr;</a>";
  288. // else echo "<span style=\"color:#bbbbbb;\">&larr;</span>";
  289. // echo "&nbsp;{$displayentrynum} {$strof} {$numentries}&nbsp;";
  290. // if ($displayentrynum < $numentries) echo "<a href=\"?id={$this->cm->id}&sloodledisplayentry=",$displayentrynum + 1,"#slide\" title=\"{$strviewnext}\">&rarr;</a>";
  291. //else echo "<span style=\"color:#bbbbbb;\">&rarr;</span>";
  292. echo "</p>\n";
  293. global $OUTPUT;
  294. echo '<div style="text-align:center;" >';
  295. echo '<table border="0" width="100%"><tr><td align="center">';
  296. $entrynumcounter=1;
  297. $jumpNumber=5;
  298. //display >>
  299. $arrowLinks = new stdClass();
  300. $arrowLinks->class='texrender';
  301. $arrowLinks->size = array('40px', '40px','40px','40px','40px');
  302. $arrowLinks->cellpadding='1';
  303. $arrowLinks->width='500px';
  304. $slideLinks= new stdClass();
  305. $slideLinks->class='texrender';
  306. $slideLinks->size = array('20px', '20px','20px','20px','20px','20px','20px');
  307. $slideLinks->cellpadding='1';
  308. $row = array();
  309. $arow = array();
  310. $start = $displayentrynum - $jumpNumber-1;
  311. if ($start>=0) $arow[]= "<a href=\"?id={$this->cm->id}&sloodledisplayentry={$start}#slide\" title=\"{$strviewjumpback} ".$jumpNumber." slides\"><img style=\"vertical-align:middle;\" alt=\"{$strviewjumpback} ".$jumpNumber." slides\" src=\"".SLOODLE_WWWROOT."/lib/media/bluecons_rewind.gif\" width=\"50\" height=\"50\"></a>";
  312. else $arow[]="<img style=\"vertical-align:middle;\" alt=\"{$strviewjumpback} ".$jumpNumber." slides\" src=\"".SLOODLE_WWWROOT."/lib/media/bluecons_rewind.gif\" width=\"50\" height=\"50\">";
  313. $prev=$displayentrynum-1;
  314. if ($displayentrynum>=2) $arow[]= "<a href=\"?id={$this->cm->id}&sloodledisplayentry={$prev}#slide\" title=\"{$strviewprev}\"><img alt=\"{$strviewprev}\" style=\"vertical-align:middle;\" src=\"".SLOODLE_WWWROOT."/lib/media/bluecons_prev.gif\" width=\"40\" height=\"40\"></a> ";
  315. else $arow[]= "<img alt=\"{$strviewprev}\" style=\"vertical-align:middle;\" src=\"".SLOODLE_WWWROOT."/lib/media/bluecons_prev.gif\" width=\"40\" height=\"40\">";
  316. // display hyperlinks for each slide
  317. $row="<table width='100%'><tr>";
  318. foreach ($entries as $entryid => $entry) {
  319. //get start and end slides
  320. $start = $displayentrynum - $jumpNumber;
  321. if ($start<0) $start =0;
  322. $end = $displayentrynum + $jumpNumber;
  323. if ($end>$numentries) $end =$numentries;
  324. if (($entrynumcounter >= $start)&& ($entrynumcounter<=$end)){
  325. if ($entrynumcounter==$displayentrynum) $row.= "<td style=\"font-weight:bold; font-size:larger;\">"."<a href=\"?id={$this->cm->id}&sloodledisplayentry=".$entrynumcounter."#slide\" title=\"{$entry->name}\">{$entrynumcounter}</a></td>";
  326. else $row.= "<td style='padding:10px'><a href=\"?id={$this->cm->id}&sloodledisplayentry=".$entrynumcounter."#slide\" title=\"{$entry->name}\">{$entrynumcounter}</td>";
  327. }
  328. $entrynumcounter++;
  329. }
  330. $row.="</tr></table>";
  331. $arow[]=$row;
  332. $end = $displayentrynum + $jumpNumber+1;
  333. $next=$displayentrynum+1;
  334. if ($displayentrynum+1 <=$numentries) $arow[]= "<a href=\"?id={$this->cm->id}&sloodledisplayentry={$next}#slide\" title=\"{$strviewnext}\"><img alt=\"{$strviewnext}\" style=\"vertical-align:middle;\" src=\"".SLOODLE_WWWROOT."/lib/media/bluecons_next.gif\" width=\"40\" height=\"40\"></a> ";
  335. else $arow[]="<img alt=\"{$strviewnext}\" style=\"vertical-align:middle;\" src=\"".SLOODLE_WWWROOT."/lib/media/greycons_next.gif\" width=\"40\" height=\"40\">";
  336. if ($end<=$numentries) $arow[]= "<a href=\"?id={$this->cm->id}&sloodledisplayentry=".$end."#slide\" title=\"{$strviewjumpforward} ".$jumpNumber." slides\"><img alt=\"{$strviewjumpforward} ".$jumpNumber."\" style=\"vertical-align:middle;\" src=\"".SLOODLE_WWWROOT."/lib/media/bluecons_fastforward.gif\" width=\"50\" height=\"50\"></a> ";
  337. else $arow[]="<img alt=\"{$strviewjumpforward} ".$jumpNumber."\" style=\"vertical-align:middle;\" src=\"".SLOODLE_WWWROOT."/lib/media/greycons_fastforward.gif\" width=\"50\" height=\"50\">";
  338. //$slideLinks->data[]=$row;
  339. $arrowLinks->data[]=$arow;
  340. echo '<div>';
  341. sloodle_print_table($arrowLinks);
  342. echo '</div>';
  343. echo "<br><br>";
  344. echo '</td></tr>';
  345. echo '</table>';
  346. echo '</div>';
  347. // Get the frame dimensions for this Presenter
  348. $framewidth = $this->presenter->get_frame_width();
  349. $frameheight = $this->presenter->get_frame_height();
  350. // Get the plugin for this slide
  351. $slideplugin = $this->_session->plugins->get_plugin('presenter-slide', $currententry->type);
  352. if (is_object($slideplugin)) {
  353. // Render the content for the web
  354. echo $slideplugin->render_slide_for_browser($currententry);
  355. } else {
  356. echo '<p style="font-size:150%; font-weight:bold; color:#880000;">',get_string('unknowntype','sloodle'),': presenter-slide::',$currententry->type, '</p>';
  357. }
  358. // Display a direct link to the media
  359. echo "<p>";
  360. print '<a href="'.$slideplugin->get_absolute_url($currententry->source).'">';
  361. print_string('trydirectlink', 'sloodle');
  362. print "</a>";
  363. echo "</p>\n";
  364. echo "</div>";
  365. } else {
  366. echo '<h4>'.get_string('presenter:empty', 'sloodle').'</h4>';
  367. if ($this->canedit) echo '<p>'.get_string('presenter:clickaddslide', 'sloodle').'</p>';
  368. }
  369. }
  370. /**
  371. * Render the Edit mode of the Presenter (lists all the slides and allows re-ordering).
  372. * Called from with the {@link render()} function when necessary.
  373. */
  374. function render_edit()
  375. {
  376. //display any feedback
  377. if (!empty($this->feedback)) echo $this->feedback;
  378. global $CFG;
  379. $streditpresenter = get_string('presenter:edit', 'sloodle');
  380. $strviewanddelete = get_string('presenter:viewanddelete', 'sloodle');
  381. $strnoentries = get_string('noentries', 'sloodle');
  382. $strnoslides = get_string('presenter:empty', 'sloodle');
  383. $strdelete = get_string('delete', 'sloodle');
  384. $stradd = get_string('presenter:add', 'sloodle');
  385. $straddatend = get_string('presenter:addatend', 'sloodle');
  386. $straddbefore = get_string('presenter:addbefore', 'sloodle');
  387. $strtype = get_string('type', 'sloodle');
  388. $strurl = get_string('url', 'sloodle');
  389. $strname = get_string('name', 'sloodle');
  390. $stryes = get_string('yes');
  391. $strno = get_string('no');
  392. $strmove = get_string('move');
  393. $stredit = get_string('edit', 'sloodle');
  394. $strview = get_string('view', 'sloodle');
  395. $strdelete = get_string('delete');
  396. $strmoveslide = get_string('presenter:moveslide', 'sloodle');
  397. $streditslide = get_string('presenter:editslide', 'sloodle');
  398. $strviewslide = get_string('presenter:viewslide', 'sloodle');
  399. $strdeleteslide = get_string('presenter:deleteslide', 'sloodle');
  400. // pixpath breaks in Moodle 2.
  401. if ( SLOODLE_IS_ENVIRONMENT_MOODLE_2 ) {
  402. global $OUTPUT;
  403. $moveheregif = $OUTPUT->pix_url('movehere');
  404. $movegif = $OUTPUT->pix_url('t/move');
  405. $editgif = $OUTPUT->pix_url('t/edit');
  406. $previewgif = $OUTPUT->pix_url('t/preview');
  407. $deletegif = $OUTPUT->pix_url('t/delete');
  408. } else {
  409. $moveheregif = "{$CFG->pixpath}/movehere.gif";
  410. $movegif = "{$CFG->pixpath}/t/move.gif";
  411. $editgif = "{$CFG->pixpath}/t/edit.gif";
  412. $previewgif = "{$CFG->pixpath}/t/preview.gif";
  413. $deletegif = "{$CFG->pixpath}/t/delete.gif";
  414. }
  415. // Get a list of entry URLs
  416. $entries = $this->presenter->get_slides();
  417. if (!is_array($entries)) $entries = array();
  418. $numentries = count($entries);
  419. // Any images to display?
  420. if ($entries === false || count($entries) == 0) {
  421. echo '<h4>'.$strnoslides.'</h4>';
  422. echo '<h4><a href="'.SLOODLE_WWWROOT.'/view.php?id='.$this->cm->id.'&amp;mode=addslide">'.$stradd.'</a></h4><br>';
  423. } else {
  424. // Are we being asked to confirm the deletion of a slide?
  425. if ($this->presenter_mode == 'confirmdeleteslide') {
  426. // Make sure the session key is specified and valid
  427. if (required_param('sesskey') != sesskey()) {
  428. error('Invalid session key');
  429. exit();
  430. }
  431. // Determine which slide is being deleted
  432. $entryid = (int)required_param('entry', PARAM_INT);
  433. // Make sure the specified entry is recognised
  434. if (isset($entries[$entryid])) {
  435. // Construct our links
  436. $linkYes = SLOODLE_WWWROOT."/view.php?id={$this->cm->id}&amp;mode=deleteslide&amp;entry={$entryid}&amp;sesskey=".sesskey();
  437. $linkNo = SLOODLE_WWWROOT."/view.php?id={$this->cm->id}&amp;mode=edit";
  438. // Output our confirmation form
  439. notice_yesno(get_string('presenter:confirmdelete', 'sloodle', $entries[$entryid]->name), $linkYes, $linkNo);
  440. echo "<br/>";
  441. }
  442. }
  443. // Are we being asked to confirm the deletion of multiple slides?
  444. $deletingentries = array();
  445. if ($this->presenter_mode == 'confirmdeletemultiple') {
  446. // Make sure the session key is specified and valid
  447. if (required_param('sesskey') != sesskey()) {
  448. error('Invalid session key');
  449. exit();
  450. }
  451. // Grab the array of entries to be deleted
  452. if (isset($_REQUEST['entries'])) $deletingentries = $_REQUEST['entries'];
  453. if (is_array($deletingentries) && count($deletingentries) > 0) {
  454. // Construct our links
  455. $entriesparam = 'entriesstr=';
  456. $delim = '';
  457. foreach($deletingentries as $de) {
  458. $entriesparam .= $delim.intval($de);
  459. $delim = ',';
  460. }
  461. $linkYes = SLOODLE_WWWROOT."/view.php?id={$this->cm->id}&amp;mode=deletemultiple&amp;{$entriesparam}&amp;sesskey=".sesskey();
  462. $linkNo = SLOODLE_WWWROOT."/view.php?id={$this->cm->id}&amp;mode=edit";
  463. // Output our confirmation form
  464. notice_yesno(get_string('presenter:confirmdeletemultiple', 'sloodle', count($deletingentries)), $linkYes, $linkNo);
  465. echo "<br/>";
  466. } else {
  467. // No slides selected.
  468. // Inform the user to select slides first, and then click the button again.
  469. notify(get_string('presenter:noslidesfordeletion', 'sloodle'));
  470. }
  471. }
  472. // Are we currently moving a slide?
  473. if ($this->presenter_mode == 'moveslide') {
  474. $linkCancel = SLOODLE_WWWROOT."/view.php?id={$this->cm->id}&amp;mode=edit";
  475. $strcancel = get_string('cancel');
  476. // Display a message and an optional 'cancel' link
  477. sloodle_print_box_start('generalbox', 'notice');
  478. echo "<p>", get_string('presenter:movingslide', 'sloodle', $entries[$this->movingentryid]->name), "</p>\n";
  479. echo "<p>(<a href=\"{$linkCancel}\">{$strcancel}</a>)</p>\n";
  480. sloodle_print_box_end();
  481. }
  482. // Setup a table object to display Presenter entries
  483. $entriesTable = new stdClass();
  484. $entriesTable->head = array(get_string('position', 'sloodle'),'<div id="selectboxes"><a href="#"><div style=\'text-align:center;\' id="selectall">'.get_string('selectall','sloodle').'</div></a></div>', get_string('name', 'sloodle'), get_string('type', 'sloodle'), get_string('actions', 'sloodle'));
  485. $entriesTable->align = array('center', 'center', 'left', 'left', 'center');
  486. $entriesTable->size = array('5%', '5%', '30%', '20%', '30%');
  487. // Go through each entry
  488. $numentries = count($entries);
  489. foreach ($entries as $entryid => $entry) {
  490. // Create a new row for the table
  491. $row = array();
  492. // Extract the entry data
  493. $slideplugin = $this->_session->plugins->get_plugin('presenter-slide', $entry->type);
  494. if (is_object($slideplugin)) $entrytypename = $slideplugin->get_plugin_name();
  495. else $entrytypename = '(unknown type)';
  496. // Construct the link to the entry source
  497. $entrylink = "<a href=\"{$entry->source}\" title=\"{$entry->source}\">{$entry->name}</a>";
  498. // If this is the slide being moved, then completely ignore it
  499. if ($this->movingentryid == $entryid) {
  500. continue;
  501. }
  502. // If we are in move mode, then add a 'move here' row before this slide
  503. if ($this->presenter_mode == 'moveslide') {
  504. $movelink = SLOODLE_WWWROOT."/view.php?id={$this->cm->id}&amp;mode=setslideposition&amp;entry={$this->movingentryid}&amp;position={$entry->slideposition}";
  505. $movebutton = "<a href=\"{$movelink}\" title=\"{$strmove}\"><img src=\"{$moveheregif}\" class=\"\" alt=\"{$strmove}\" /></a>\n";
  506. $entriesTable->data[] = array('', '', $movebutton, '', '', '');
  507. // If the current row belongs to the slide being moved, then emphasise it, and append (moving) to the end
  508. if ($entryid == $this->movingentryid) $entrylink = "<strong>{$entrylink}</strong> <em>(".get_string('moving','sloodle').')</em>';
  509. }
  510. // Define our action links
  511. $actionBaseLink = SLOODLE_WWWROOT."/view.php?id={$this->cm->id}";
  512. $actionLinkMove = $actionBaseLink."&amp;mode=moveslide&amp;entry={$entryid}";
  513. $actionLinkEdit = $actionBaseLink."&amp;mode=editslide&amp;entry={$entryid}";
  514. $actionLinkView = $actionBaseLink."&amp;mode=view&amp;sloodledisplayentry={$entry->slideposition}#slide";
  515. $actionLinkDelete = $actionBaseLink."&amp;mode=confirmdeleteslide&amp;entry={$entryid}&amp;sesskey=".sesskey();
  516. // Prepare the add buttons separately
  517. $actionLinkAdd = $actionBaseLink."&amp;mode=addslide&amp;sloodleentryposition={$entry->slideposition}";
  518. $addButtons = "<a href=\"{$actionLinkAdd}\" title=\"{$straddbefore}\"><img src=\"".SLOODLE_WWWROOT."/lib/media/add.png\" alt=\"{$stradd}\" /></a>\n";
  519. // Construct our list of action buttons
  520. $actionButtons = '';
  521. $actionButtons .= "<a href=\"{$actionLinkMove}\" title=\"{$strmoveslide}\"><img src=\"{$movegif}\" class=\"iconsmall\" alt=\"{$strmove}\" /></a>\n";
  522. $actionButtons .= "<a href=\"{$actionLinkEdit}\" title=\"{$streditslide}\"><img src=\"{$editgif}\" class=\"iconsmall\" alt=\"{$stredit}\" /></a>\n";
  523. $actionButtons .= "<a href=\"{$actionLinkView}\" title=\"{$strviewslide}\"><img src=\"{$previewgif}\" class=\"iconsmall\" alt=\"{$strview}\" /></a>\n";
  524. $actionButtons .= "<a href=\"{$actionLinkDelete}\" title=\"{$strdeleteslide}\"><img src=\"{$deletegif}\" class=\"iconsmall\" alt=\"{$strdelete}\" /></a>\n";
  525. $actionButtons .= $addButtons;
  526. //create checkbox for multiple edit functions
  527. $checked = '';
  528. if (in_array($entryid, $deletingentries)) $checked = "checked=\"checked\"";
  529. $checkbox = "<div style='text-align:center;'><input type=\"checkbox\" name=\"entries[]\" {$checked} value=\"{$entryid}\" /></div>";
  530. // Add each item of data to our table row.
  531. // The first item is a check box for multiple deletes
  532. // The second items are the position and the name of the entry, hyperlinked to the resource.
  533. // The next is the name of the entry type.
  534. // The last is a list of action buttons -- move, edit, view, and delete.
  535. $row[] = $entry->slideposition;
  536. $row[] = $checkbox;
  537. $row[] = $entrylink;
  538. $row[] = $entrytypename;
  539. $row[] = $actionButtons;
  540. // Add the row to our table
  541. $entriesTable->data[] = $row;
  542. }
  543. // If we are in move mode, then add a final 'move here' row at the bottom
  544. // We need to add a final row at the bottom
  545. // Prepare the action link for this row
  546. $endentrynum = $entry->slideposition + 1;
  547. $actionLinkAdd = $actionBaseLink."&amp;mode=addslide&amp;sloodleentryposition={$endentrynum}";
  548. $addButtons = "<a href=\"{$actionLinkAdd}\" title=\"{$straddatend}\"><img src=\"".SLOODLE_WWWROOT."/lib/media/add.png\" alt=\"{$stradd}\" /></a>\n";
  549. $sloodleInsert = get_string("presenter:sloodleinsert","sloodle");
  550. // It will contain a last 'add' button, and possibly a 'move here' button too (if we are in move mode)
  551. $movebutton = '';
  552. if ($this->presenter_mode == 'moveslide') {
  553. $movelink = SLOODLE_WWWROOT."/view.php?id={$this->cm->id}&amp;mode=setslideposition&amp;entry={$this->movingentryid}&amp;position={$endentrynum}";
  554. $movebutton = "<a href=\"{$movelink}\" title=\"{$strmove}\"><img src=\"{$moveheregif}\" class=\"\" alt=\"{$strmove}\" /></a>\n";
  555. }
  556. // Add a button to delete all selected slides
  557. $deleteButton = '<input type="submit" value="'.get_string('deleteselected','sloodle').'" />';
  558. $entriesTable->data[] = array('',' <div id="selectboxes2"><a href="#"><div style=\'text-align:center;\' id="selectall2">'.get_string('selectall','sloodle').'</div></a></div>', $movebutton , '', $deleteButton.'&nbsp;&nbsp;'.$addButtons);
  559. // Put our table inside a form to allow us to delete multiple slides based on the checkboxes
  560. echo '<form action="" method="get" id="editform" name="editform">';
  561. echo "<input type=\"hidden\" name=\"id\" value=\"{$this->cm->id}\" />\n"; // Course module ID so that the request comes to the right places
  562. echo "<input type=\"hidden\" name=\"mode\" value=\"confirmdeletemultiple\" />\n"; // The operation being conducted
  563. sloodle_print_table($entriesTable);
  564. echo "<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />\n"; // Session key to ensure unauthorised deletions are not possible (e.g. using XSS)
  565. echo '</form>';
  566. }
  567. }
  568. /**
  569. * Render the "Upload Many" tab.
  570. */
  571. function render_add_files()
  572. {
  573. global $CFG;
  574. global $USER;
  575. /*
  576. Normally Moodle would use the itemid for something that the image belongs to, eg. a forum post.
  577. We don't really need one here - we have slides, but they are assigned after the file has been uploaded.
  578. We'll set this parameter to a unique ID per upload page.
  579. This will prevent clashes if you try to re-upload another file with the same name.
  580. (The upload component expects to know what the name of the uploaded file will be, so we have to assign it before doing the upload.)
  581. */
  582. $itemid = time();
  583. // Setup variables to store the data
  584. $entryid = 0;
  585. $entryname = '';
  586. $entryurl = '';
  587. $entrytype = '';
  588. // Fetch a list of existing slides
  589. $entries = $this->presenter->get_entry_urls();
  590. // Check what position we are adding the new slide to
  591. // (default to negative, which puts it at the end)
  592. $position = (int)optional_param('sloodleentryposition', '-1', PARAM_INT);
  593. // Fetch our translation strings
  594. $streditpresenter = get_string('presenter:edit', 'sloodle');
  595. $strviewanddelete = get_string('presenter:viewanddelete', 'sloodle');
  596. $strnoentries = get_string('noentries', 'sloodle');
  597. $strdelete = get_string('delete', 'sloodle');
  598. $strBulkUpload = get_string('presenter:bulkupload', 'sloodle');
  599. $stradd = get_string('presenter:addfiles', 'sloodle');
  600. $strtype = get_string('type', 'sloodle');
  601. $strurl = get_string('url', 'sloodle');
  602. $strname = get_string('name', 'sloodle');
  603. $strposition = get_string('position', 'sloodle');
  604. $strsave = get_string('save', 'sloodle');
  605. $strend = get_string('end', 'sloodle');
  606. $stryes = get_string('yes');
  607. $strno = get_string('no');
  608. $strcancel = get_string('cancel');
  609. $strmove = get_string('move');
  610. $stredit = get_string('edit', 'sloodle');
  611. $strview = get_string('view', 'sloodle');
  612. $strdelete = get_string('delete');
  613. // Construct an array of available entry types, associating the identifier to the human-readable name.
  614. // In future, this will be built from a list of plugins, but for now we'll hard code it.
  615. $availabletypes = array();
  616. $availabletypes['image'] = get_string('presenter:type:image','sloodle');
  617. $availabletypes['video'] = get_string('presenter:type:video','sloodle');
  618. $availabletypes['web'] = get_string('presenter:type:web','sloodle');
  619. //display instructions
  620. echo get_string('presenter:uploadInstructions','sloodle');
  621. // We'll post the data straight back to this page
  622. echo '<form action="" method="post"><fieldset style="border-style:none;">';
  623. // Identify the module
  624. /*
  625. * Uploadify Multiple File uploader added by Paul Preibisch
  626. * @see http://www.uploadify.com/documentation
  627. *
  628. * @var uploadWwwDir - place to store files
  629. * @var uploadArray[] - array to hold complete file names
  630. * @var extension - temp var to hold extension type of current file
  631. * @var tableData - used to construct table rows
  632. * @uses upload.php - upload.php is the upload handler script
  633. * @uses uploader.swf - enables multiple file uploading
  634. */
  635. $context = get_context_instance(CONTEXT_MODULE, $this->cm->id);
  636. $contextid = $context->id;
  637. echo '<script type="text/javascript">';
  638. if (SLOODLE_IS_ENVIRONMENT_MOODLE_2) {
  639. echo 'var uploadWwwDir="'.$CFG->wwwroot.'/pluginfile.php/'.intval($contextid).'/mod_sloodle/presenter/'.intval($itemid).'/'.'";'."\n";
  640. } else {
  641. echo 'var uploadWwwDir="'.$CFG->wwwroot.'/file.php/1/presenter/'.intval($this->cm->id).'/";'."\n";
  642. }
  643. echo 'var uploadArray = [];'."\n";
  644. echo 'var qSize=0;'."\n";
  645. echo 'var uploadLimit='.((integer)INI_GET('post_max_size')*1000000).';'."\n";
  646. echo 'var uploadArrayLen=0;'."\n";
  647. echo 'var counter=0;'."\n";
  648. echo 'var extension=\'\';'."\n";
  649. echo 'var tableData=\'\';'."\n";
  650. echo 'var cmid = '.intval($this->cm->id)."\n";
  651. echo 'var itemid = '.intval($itemid)."\n";
  652. echo "var stradd = '".s($stradd)."';\n";
  653. $signeddata = date('Ymd').'-'.intval($USER->id).'-'.intval($this->cm->id).'-'.'presenter';
  654. echo "var signeddata = '".s($signeddata)."';"."\n";
  655. echo "var signature = '".s(sloodle_signature($signeddata))."';"."\n";
  656. echo "</script>";
  657. echo '<input type="file" name="fileInput" id="fileInput" />';
  658. //this div is where the uploaded files will be displayed
  659. echo '<div name="filesUploaded" id="filesUploaded"><div name="fileTables" id="fileTables"></div></div>';
  660. echo '<div name="qSize" id="qSize"></div></fieldset>';
  661. echo '<div style="display:none;" name="uploadButton" id="uploadButton"><a href="javascript:startUpload(\'fileUpload\')">Start Upload</a></div></form>';
  662. // Add a button to let us cancel and go back to the main edit tab
  663. echo '<form action="" method="get"><fieldset style="border-style:none;">';
  664. echo "<input type=\"hidden\" name=\"id\" value=\"{$this->cm->id}\" />";
  665. echo "<input type=\"hidden\" name=\"mode\" value=\"edit\" />";
  666. echo "<input type=\"submit\" value=\"{$strcancel}\" />";
  667. echo '</fieldset></form>';
  668. }
  669. /**
  670. * Render the slide editing form of the Presenter (lets you edit a single slide).
  671. * Called from with the {@link render()} function when necessary.
  672. */
  673. function render_slide_edit()
  674. {
  675. // Setup variables to store the data
  676. $entryid = 0;
  677. $entryname = '';
  678. $entryurl = '';
  679. $entrytype = '';
  680. // Fetch a list of existing slides
  681. $entries = $this->presenter->get_slides();
  682. // Check what position we are adding the new slide to
  683. // (default to negative, which puts it at the end)
  684. $position = (int)optional_param('sloodleentryposition', '-1', PARAM_INT);
  685. // Are we adding a slide, or editing one?
  686. $newslide = false;
  687. if ($this->presenter_mode == 'addslide') {
  688. // Adding a new slide
  689. $newslide = true;
  690. // Grab the last added type from session data
  691. if (isset($_SESSION['sloodle_presenter_add_type'])) $entrytype = $_SESSION['sloodle_presenter_add_type'];
  692. } else {
  693. // Editing an existing slide
  694. $entryid = (int)required_param('entry', PARAM_INT);
  695. // Fetch the slide details
  696. if (!isset($entries[$entryid])) {
  697. error("Cannot find entry {$entryid} in the database.");
  698. exit();
  699. }
  700. $entryurl = $entries[$entryid]->source;
  701. $entrytype = $entries[$entryid]->type;
  702. $entryname = $entries[$entryid]->name;
  703. }
  704. // Fetch our translation strings
  705. $streditpresenter = get_string('presenter:edit', 'sloodle');
  706. $strviewanddelete = get_string('presenter:viewanddelete', 'sloodle');
  707. $strnoentries = get_string('noentries', 'sloodle');
  708. $strdelete = get_string('delete', 'sloodle');
  709. $stradd = get_string('presenter:add', 'sloodle');
  710. $strtype = get_string('type', 'sloodle');
  711. $strurl = get_string('url', 'sloodle');
  712. $strname = get_string('name', 'sloodle');
  713. $strposition = get_string('position', 'sloodle');
  714. $strsave = get_string('save', 'sloodle');
  715. $strend = get_string('end', 'sloodle');
  716. $stryes = get_string('yes');
  717. $strno = get_string('no');
  718. $strcancel = get_string('cancel');
  719. $strmove = get_string('move');
  720. $stredit = get_string('edit', 'sloodle');
  721. $strview = get_string('view', 'sloodle');
  722. $strdelete = get_string('delete');
  723. // Construct an array of available entry types, associating the identifier to the human-readable name.
  724. $availabletypes = array();
  725. $pluginids = $this->_session->plugins->get_plugin_ids('presenter-slide');
  726. if (!$pluginids) exit('Failed to query for SLOODLE Presenter slide plugins.');
  727. foreach ($pluginids as $pluginid) {
  728. // Fetch the plugin and store its human-readable name
  729. $plugin = $this->_session->plugins->get_plugin('presenter-slide', $pluginid);
  730. $availabletypes[$pluginid] = $plugin->get_plugin_name();
  731. }
  732. // We'll post the data straight back to this page
  733. echo '<form action="" method="post"><fieldset style="border-style:none;">';
  734. // Identify the module
  735. echo "<input type=\"hidden\" name=\"id\" value=\"{$this->cm->id}\" />";
  736. // Identify the entry being edited, if appropriate
  737. if (!$newslide) echo "<input type=\"hidden\" name=\"sloodleentryid\" value=\"{$entryid}\" />";
  738. // Add boxes for the URL and name of the entry
  739. echo '<label for="sloodleentryname">'.$strname.': </label> <input type="text" id="sloodleentryname" name="sloodleentryname" value="'.$entryname.'" size="100" maxlength="255" /><br/><br/>';
  740. echo '<label for="sloodleentryurl">'.$strurl.': </label> <input type="text" id="sloodleentryurl" name="sloodleentryurl" value="'.$entryurl.'" size="100" maxlength="255" /><br/><br/>';
  741. // Add a selection box for the entry type
  742. echo '<label for="sloodleentrytype">'.$strtype.': </label> <select name="sloodleentrytype" id="sloodleentrytype" size="1">';
  743. foreach ($availabletypes as $typeident => $typename) {
  744. echo "<option value=\"{$typeident}\"";
  745. if ($typeident == $entrytype) echo " selected=\"selected\"";
  746. echo ">{$typename}</option>";
  747. }
  748. echo '</select><br/><br/>';
  749. // Add a selection box to let the user change the position of the entry
  750. echo '<label for="sloodleentryposition">'.$strposition.': </label> <select name="sloodleentryposition" id="sloodleentryposition" size="1">'."\n";
  751. $selected = false;
  752. foreach ($entries as $curentryid => $curentry) {
  753. // Add this entry to the list
  754. echo "<option value=\"{$curentry->slideposition}\"";
  755. if ($curentry->slideposition == $position || $curentryid == $entryid) {
  756. echo ' selected="selected"';
  757. $selected = true;
  758. }
  759. echo ">{$curentry->slideposition}: {$curentry->name}</option>\n";
  760. }
  761. // Add an 'end' option so that the entry can be placed at the end of the presentation
  762. $endentrynum = $curentry->slideposition + 1;
  763. echo "<option value=\"{$endentrynum}\"";
  764. if (!$selected) echo " selected=\"selected\"";
  765. echo ">--{$strend}--</option>\n";
  766. echo "</select><br/><br/>\n";
  767. // Display an appropriate submit button
  768. if ($newslide) echo ' <input type="submit" value="'.$stradd.'" name="sloodleaddentry" />';
  769. else echo ' <input type="submit" value="'.$strsave.'" name="sloodleeditentry" />';
  770. // Close the form
  771. echo '</fieldset></form>';
  772. // Add a button to let us cancel and go back to the main edit tab
  773. echo '<form action="" method="get"><fieldset style="border-style:none;">';
  774. echo "<input type=\"hidden\" name=\"id\" value=\"{$this->cm->id}\" />";
  775. echo "<input type=\"hidden\" name=\"mode\" value=\"edit\" />";
  776. echo "<input type=\"submit\" value=\"{$strcancel}\" />";
  777. echo '</fieldset></form>';
  778. }
  779. /**
  780. * Render the tab for importing slides from some source.
  781. * If necessary, this will first display a form letting the user select which importer to use.
  782. * It will then rely on the plugin to sort out everything else.
  783. */
  784. function render_import_slides()
  785. {
  786. global $CFG;
  787. // Construct an array of available importers, associating the identifier to the human-readable name.
  788. $availableimporters = array();
  789. $pluginids = $this->_session->plugins->get_plugin_ids('presenter-importer');
  790. if (!$pluginids) error('Failed to load any SLOODLE Presenter importer plugins. Please check your plugins folder.');
  791. foreach ($pluginids as $pluginid) {
  792. // Fetch the plugin and store its human-readable name
  793. $plugin = $this->_session->plugins->get_plugin('presenter-importer', $pluginid);
  794. $availableimporters[$pluginid] = $plugin->get_plugin_name();
  795. }
  796. // We are expecting a few parameters
  797. $position = (int)optional_param('sloodleentryposition', '-1', PARAM_INT);
  798. $plugintype = strtolower(optional_param('sloodleplugintype', '', PARAM_CLEAN));
  799. // Fetch translation strings
  800. $strselectimporter = get_string('presenter:selectimporter', 'sloodle');
  801. $strsubmit = get_string('submit');
  802. $strincompatible = get_string('incompatible', 'sloodle');
  803. $strcompatible = get_string('compatible', 'sloodle');
  804. $strincompatibleplugin = get_string('incompatibleplugin', 'sloodle');
  805. $strcheck = get_string('check', 'sloodle');
  806. $strclicktocheck = get_string('clicktocheckcompatibility', 'sloodle');
  807. $strclicktochecknoperm = get_string('clicktocheckcompatibility:nopermission', 'sloodle');
  808. // Do we have a valid plugin type already specified?
  809. if (empty($plugintype) || !array_key_exists($plugintype, $availableimporters)) {
  810. // No - display a menu to select the desired importer
  811. // Sort the list of importers by name
  812. natcasesort($availableimporters);
  813. // Setup a base link for all importer types
  814. $baselink = "{$CFG->wwwroot}/mod/sloodle/view.php?id={$this->cm->id}&amp;mode=importslides";
  815. // Setup a base link for checking compatibility
  816. $checklink = "{$CFG->wwwroot}/mod/sloodle/view.php?id={$this->cm->id}&amp;mode=compatibility";
  817. // Make sure this user has site configuration permission, as running this test may reveal sensitive information about server architecture
  818. $module_context = get_context_instance(CONTEXT_MODULE, $this->cm->id);
  819. $cancheckcompatibility = (bool)has_capability('moodle/site:config', $module_context);
  820. // Go through each one and display it in a menu
  821. $table = new stdClass();
  822. $table->head = array(get_string('name', 'sloodle'), get_string('description'), get_string('compatibility', 'sloodle'));
  823. $table->size = array('20%', '70%', '10%');
  824. $table->align = array('center', 'left', 'center');
  825. $table->data = array();
  826. foreach ($availableimporters as $importerident => $importername) {
  827. // Get the description of the plugin
  828. $plugin = $this->_session->plugins->get_plugin('presenter-importer', $importerident);
  829. $desc = $plugin->get_plugin_description();
  830. // Check the compatibility of the plugin
  831. $linkclass = '';
  832. $compatibility = '';
  833. if (!$plugin->check_compatibility()) {
  834. $linkclass = ' class="dimmed"';
  835. $compatibility = '<abbr title="'.$plugin->get_compatibility_summary().'"><span class="highlight2" style="font-weight:bold;">[ '.$strincompatible.' ]</span></abbr>';
  836. }
  837. // Construct this line of the table
  838. $line = array();
  839. // Add the name of the importer to the table as a link
  840. $link = "{$baselink}&amp;sloodleplugintype={$importerident}";
  841. $line[] = "<span style=\"font-size:120%; font-weight:bold;\"><a href=\"{$link}\" title=\"{$desc}\" {$linkclass}>{$importername}</a></span><br/>{$compatibility}";
  842. // Add the description
  843. $line[] = $desc;
  844. // Add a link to a compatibility check if the user has permission.
  845. if ($cancheckcompatibility) {
  846. $link = "{$checklink}&amp;sloodleplugintype={$importerident}";
  847. $line[] = "<a href=\"{$link}\" title=\"{$strclicktocheck}\">{$strcheck}</a>";
  848. } else {
  849. $line[] = "<span title=\"{$strclicktochecknoperm}\">-</span>";
  850. }
  851. $table->data[] = $line;
  852. }
  853. echo "<h4>{$strselectimporter}: </h4>\n";
  854. sloodle_print_table($table);
  855. return;
  856. }
  857. // Grab the importer plugin object
  858. $importer = $this->_session->plugins->get_plugin('presenter-importer', $plugintype);
  859. // Display a heading for this importer
  860. echo '<h2 style="margin-bottom:0px; padding-bottom:0px;">'.$importer->get_plugin_name()."</h2>\n";
  861. // Render the plugin display
  862. $importer->render("{$CFG->wwwroot}/mod/sloodle/view.php?id={$this->cm->id}", $this->presenter);
  863. }
  864. /**
  865. * Render a compatibility test of a particular plugin.
  866. */
  867. function render_compatibility_test()
  868. {
  869. global $CFG;
  870. // Which plugin has been requested?
  871. $plugintype = strtolower(required_param('sloodleplugintype', PARAM_CLEAN));
  872. // Attempt to load the specified plugin
  873. $plugin = $this->_session->plugins->get_plugin('presenter-importer', $plugintype);
  874. if ($plugin === false) exit(get_string('pluginloadfailed', 'sloodle'));
  875. $name = $plugin->get_plugin_name();
  876. // Make sure this user has site configuration permission, as running this test may reveal sensitive information about server architecture
  877. $module_context = get_context_instance(CONTEXT_MODULE, $this->cm->id);
  878. if (!has_capability('moodle/site:config', $module_context)) error(get_string('clicktocheckcompatibility:nopermission', 'sloodle'), "{$CFG->wwwroot}/mod/sloodle/view.php?id={$this->cm->id}&amp;mode=importslides");
  879. // Display a heading for this compatibility check
  880. echo '<h1>',get_string('runningcompatibilitycheck', 'sloodle'),'</h1>';
  881. echo '<h2>'.$name."</h2>\n";
  882. echo "<p>( <a href=\"{$CFG->wwwroot}/mod/sloodle/view.php?id={$this->cm->id}&amp;mode=importslides\">",get_string('presenter:backtoimporters','sloodle'),"</a> )</p>\n";
  883. // Run the compatibility test
  884. echo "<div style=\"text-align:left;\">";
  885. $result = $plugin->run_compatibility_test();
  886. echo "</div>\n";
  887. if ($result) echo "<h1>",get_string('compatibilitytestpassed', 'sloodle'),"</h1>";
  888. else echo "<h1>",get_string('compatibilitytestfailed', 'sloodle'),"</h1>";
  889. echo "<p>( <a href=\"{$CFG->wwwroot}/mod/sloodle/view.php?id={$this->cm->id}&amp;mode=importslides\">",get_string('presenter:backtoimporters','sloodle'),"</a> )</p>\n";
  890. }
  891. /**
  892. * Render the view of the Presenter.
  893. */
  894. function render()
  895. {
  896. global $CFG;
  897. // Setup our list of tabs
  898. // We will always have a view option
  899. $presenterTabs = array(); // Top level is rows of tabs
  900. $presenterTabs[0] = array(); // Second level is individual tabs in a row
  901. $presenterTabs[0][] = new tabobject(SLOODLE_PRESENTER_TAB_VIEW, SLOODLE_WWWROOT."/view.php?id={$this->cm->id}&amp;mode=view", get_string('view', 'sloodle'), get_string('presenter:viewpresentation', 'sloodle'), true);
  902. // Does the user have authority to edit this module?
  903. if ($this->canedit) {
  904. // Add the 'Edit' tab, for editing the presentation as a whole
  905. $presenterTabs[0][] = new tabobject(SLOODLE_PRESENTER_TAB_EDIT, SLOODLE_WWWROOT."/view.php?id={$this->cm->id}&amp;mode=edit", get_string('edit', 'sloodle'), get_string('presenter:edit', 'sloodle'), true);
  906. // Add the 'Add Slide' tab
  907. $presenterTabs[0][] = new tabobject(SLOODLE_PRESENTER_TAB_ADD_SLIDE, SLOODLE_WWWROOT."/view.php?id={$this->cm->id}&amp;mode=addslide", get_string('presenter:add', 'sloodle'), get_string('presenter:add', 'sloodle'), true);
  908. // Add the 'Bulk Upload' tab
  909. $presenterTabs[0][] = new tabobject(SLOODLE_PRESENTER_TAB_ADD_FILES, SLOODLE_WWWROOT."/view.php?id={$this->cm->id}&amp;mode=addfiles", get_string('presenter:bulkupload', 'sloodle'), get_string('presenter:bulkupload', 'sloodle'), true);
  910. // Add the 'Import Slides' tab
  911. $presenterTabs[0][] = new tabobject(SLOODLE_PRESENTER_TAB_IMPORT_SLIDES, SLOODLE_WWWROOT."/view.php?id={$this->cm->id}&amp;mode=importslides", get_string('presenter:importslides', 'sloodle'), get_string('presenter:importslides', 'sloodle'), true);
  912. // If we are editing a slide, then add the 'Edit Slide' tab
  913. if ($this->presenter_mode == 'editslide') {
  914. $presenterTabs[0][] = new tabobject(SLOODLE_PRESENTER_TAB_EDIT_SLIDE, '', get_string('editslide', 'sloodle'), '', false);
  915. }
  916. }
  917. // Determine which tab should be active
  918. $selectedtab = SLOODLE_PRESENTER_TAB_VIEW;
  919. switch ($this->presenter_mode)
  920. {
  921. case 'edit': $selectedtab = SLOODLE_PRESENTER_TAB_EDIT; break;
  922. case 'addslide': $selectedtab = SLOODLE_PRESENTER_TAB_ADD_SLIDE; break;
  923. case 'addfiles': $selectedtab = SLOODLE_PRESENTER_TAB_ADD_FILES; break;
  924. case 'editslide': $selectedtab = SLOODLE_PRESENTER_TAB_EDIT_SLIDE; break;
  925. case 'moveslide': $selectedtab = SLOODLE_PRESENTER_TAB_EDIT; break;
  926. case 'deleteslide': $selectedtab = SLOODLE_PRESENTER_TAB_EDIT; break;
  927. case 'confirmdeleteslide': $selectedtab = SLOODLE_PRESENTER_TAB_EDIT; break;
  928. case 'deletemultiple': $selectedtab = SLOODLE_PRESENTER_TAB_EDIT; break;
  929. case 'confirmdeletemultiple': $selectedtab = SLOODLE_PRESENTER_TAB_EDIT; break;
  930. case 'importslides': $selectedtab = SLOODLE_PRESENTER_TAB_IMPORT_SLIDES; break;
  931. case 'compatibility': $selectedtab = SLOODLE_PRESENTER_TAB_IMPORT_SLIDES; break;
  932. }
  933. // Display the tabs
  934. print_tabs($presenterTabs, $selectedtab);
  935. echo "<div style=\"text-align:center;\">\n";
  936. // Call the appropriate render function, based on our mode
  937. switch ($this->presenter_mode)
  938. {
  939. case 'edit': $this->render_edit(); break;
  940. case 'addslide': $this->render_slide_edit(); break;
  941. case 'addfiles': $this->render_add_files(); break;
  942. case 'editslide': $this->render_slide_edit(); break;
  943. case 'moveslide': $this->render_edit(); break;
  944. case 'deleteslide': $this->render_edit(); break;
  945. case 'confirmdeleteslide': $this->render_edit(); break;
  946. case 'deletemultiple': $this->render_edit(); break;
  947. case 'confirmdeletemultiple': $this->render_edit(); break;
  948. case 'importslides': $this->render_import_slides(); break;
  949. case 'compatibility': $this->render_compatibility_test(); break;
  950. default: $this->render_view(); break;
  951. }
  952. echo "</div>\n";
  953. }
  954. }
  955. ?>