Flash module add-on: Connecting my quizzes to Moodle

Flash module add-on: Connecting my quizzes to Moodle

by Andrew Field -
Number of replies: 6
Hi - I was involved in a discussion this time last year about getting Flash to communicate with Moodle.  I run a site called http://www.contentgenerator.net/- here I have a number of Flash quizzes and activities, some free, others pay for.

If I can get this working I will of course, release the finished free quizzes so other Moodle colleagues can use them.  My Flash quizzes, in my opinion, are a great way of engaging students and would be a great of providing students with assessment opportunities.

Anyway, Jamie suggested I post the outline of the previous discussion here in the hope that I can get things working. wink

The previous discussion can be found here. [External link to my forum]

Lengthy summary here:

Jamie:
Here is a service.php file that you should put in the same directory as your movie :

CODE

<?php
global $CFG;
require("$CFG->dirroot/mod/flash/movies/send_answer.php");
class service extends send_answer
{
  var $_frmCredentials;
   
   function service($toPass)
   {
 //this will allow you to access the first name of the user
       global $USER, $CFG;
       parent::send_answer($toPass);//default constructor
 $this->userFirstName=$USER->firstname;
   }
   function answers($answers, $grades)
   // pass answers to this function in an array with question 1's answer in
   // $answers[1] etc and grade for q 1 in $grades[1]
   {
       for ($n=1; $n++; $n<=count($answers))
       {
           $anstodb=array('answer'=>$answers[$n]);
           parent::answer(1, $anstodb, $grades[$n]);//always pass a q no : 1 and a grade : 100 %
           return true;
       };
   }
}
   
?>


The Flash activity module lets you call the functions on this class directly from your action script.

So somewhere in your script in response to some event you initialise the object as so :

CODE

onClipEvent (load) {
// first request username
this._visible = false;
_root.firstname = "default";
moodleService.onInit=function()
{
 _root.firstname = moodleService.userFirstName;
 _root.dreams =moodleService.oldanswer;
 _root.gotoAndPlay("Intro");
}
moodleService.init();
}


init() will call the constructor on the service.php class - the function called service(). This will give you access to the firstname of the user and you can then use that in your movie. You could access other data through this init function such as some questions and answers stored in the Moodle db.

See how onInit is called on return from the php function and then moodleService.userFirstName will contain the username.


Similarly you can send your answers to Moodle by calling the moodleService.answers function, for example in response to an onRelease event :

CODE
onRelease () {
moodleService.answers_onResult=function()
       //results have been stored
{
 _root.gotoAndPlay("End");
}
moodleService.answers(_root.arrayWithAnswersIn, _root.arrayWithGradesIn);
}


Use the 'preloader' this will set up all the remoting code for you.

WHen your movie is finished call :

CODE
moodleService.cleanUp('course'); // this will take you back to the course page after
                                              //cleaning up session vars


Or :

CODE
moodleService.cleanUp(); // this will take you back to the results page for this
                                     // activity after
                                     //cleaning up session vars


Or :

CODE
moodleService.cleanUp(URL); // this will take you to URL
                                     // activity after
                                     //cleaning up session vars



Hope this helps.

Have a good read through the info I put up on my wiki as well.

Me (Andrew)
Just to check - this code still seems to send the answers etc. to Moodle.  Do I really need to do this?

Within the multi-choice generator I can handle all the question data - I don't think I need to share this with Moodle.

All I'm looking to do is pass the final result to Moodle i.e. tell Moodle that the user got 100% in the quiz and then record that in the database.


Jamie:
Hi Andrew,

Yes, but why not send the answers to Moodle. It doesn't require much work. Then the test creator will have the option of letting users see answers they have given to questions and teachers will see what answers there students have submitted. The test creator can choose what guest users will see, probably you wouldn't show a guest user answers submitted by other guests and the grade they got for them.

additional post:

If you really just want to send one score for the whole activity you should do somthing like this :

Use this service.php file that you should put in the same directory as your movie :

CODE

<?php
global $CFG;
require("$CFG->dirroot/mod/flash/movies/send_answer.php");
class service extends send_answer
{
  var $_frmCredentials;
   
   function service($grade, $toPass)
   {
 //this will allow you to access the first name of the user
       global $USER, $CFG;
       parent::send_answer($toPass);//default constructor
       parent::answer(1, array(), $grade);//always pass a q no : 1 and blank answer
   }
}
   
?>


And just before you finish the movie use something like this :

CODE

onRelease () {
// first request username
moodleService.onInit=function()
{
           moodleService.cleanUp('course');
       }
moodleService.init(grade);//pass the grade to Moodle
}


init() will call the constructor on the service.php class. And then when it returns the cleanUp function will be called which will end your movie and jump to the course view in Moodle.


additional post:

I saw a mistake in my first service.php code :

CODE
   function answers($answers, $grades)
  // pass answers to this function in an array with question 1's answer in
  // $answers[1] etc and grade for q 1 in $grades[1]
  {
      for ($n=1; $n++; $n<=count($answers))
      {
          $anstodb=array('answer'=>$answers[$n]);
          parent::answer(1, $anstodb, $grades[$n]);//always pass a q no : 1 and a grade : 100 %
          return true;
      };
  }
}


Move the return true; to just after the for loop.

My reply:

Well, I've got the multi-choice generator 'working' within Moodle, as part of a Flash module.

sad.gif However - all of the commands that I'm trying to use to send the data, to communicate with the Moodle database seem to be failing to connect.

For example, the movie just hangs when I call the following
CODE
onClipEvent (load) {
// first request username
this._visible = false;
_root.firstname = "default";
moodleService.onInit=function()
{
_root.firstname = moodleService.userFirstName;
_root.dreams =moodleService.oldanswer;
_root.gotoAndPlay("start");
}
moodleService.init();
}

I'll keep trying! It just seems that I'm not 'connecting' the .swf to the database.

I think I'll try the basic one now - just to see if I can make anything happen. I'm sure this will be possible, it is just about fiddling with all the settings and scripting.

My next post:

Nope sad.gif

I've uploaded the following attempt:
http://www.effectiveict.co.uk/moodle/mod/f.../view.php?id=10

This gets stuck when the Moodle logo appears. This is a MovieClip with the following code attached:
CODE
onClipEvent (load) {
// first request username
//this._visible = false;
_root.firstName = "default";

moodleService.onInit=function()
{
_root.firstName = moodleService.userFirstName;
_root.dreams =moodleService.oldanswer;
_root.gotoAndPlay("start");
}
moodleService.init();
}


It seems that the .swf never communicates with Moodle, and thus the gotoAndPlay("start") never happens sad.gif

Bit stuck with it really as this is obviously a key thing.

Jamie's reply:
This is where the debugging features of the module come in handy.

You can use in Flash :

moodleDebugger.addText('Saving');

Which will output 'Saving' to the debug view. (The debug view is what you see when the movie is loading and you can press CTRL-D to switch to the debug view at any time - this switching unfortunately doesn't work in IE, IE hogs the keys and Flash can't detect this key combo in IE)

And in PHP anything you output using echo, print_r, print, etc will be output to the debug view in Flash upon return from calling the function.

Jamie's reply:
You can also do this to check that your service file is being parsed correctly. Add a file with this contents in the same directory as your movie :

CODE

<?php
include ('../../../../config.php');
include ('./service.php');
?>


Just to check for any parse errors of your class file. Point to the file with your browser and hopefully there will be no parse errors.

You aren't using php5 are you? You are aware that the module doesn't yet work with php5 aren't you?

I then got stuck - confirmed that I wasn't using php5, but then wasn't able to make more progress.  I'm now keep to get this going again.  Any help anyone can give would be great.  I'm basically looking to pass some variables from my Flash quiz to Moodle.
Average of ratings: -
In reply to Andrew Field

Re: Flash module add-on: Connecting my quizzes to Moodle

by Jamie Pratt -
Thanks for reposting this discussion here Andrew.

Everyone please notice that the Moodle Forums have replaced :

onInit

with

XonInit

Several places in the code. You'll need to change these back if you want to use this code.
In reply to Andrew Field

Re: Flash module add-on: Connecting my quizzes to Moodle

by Jamie Pratt -
So I suggest you do these next Andrew :

You can also do this to check that your service file is being parsed correctly. Add a file with this contents in the same directory as your movie :

CODE

<?php
include ('../../../../config.php');
include ('./service.php');
?>


Just to check for any parse errors of your class file. Point to the file with your browser and hopefully there will be no parse errors.


And try adding moodleDebugger.addText('Saving');  to :

onClipEvent (load) {
// first request username
//this._visible = false;
_root.firstName = "default";

moodleService.XonInit=function()
{
_root.firstName = moodleService.userFirstName;
_root.dreams =moodleService.oldanswer;
_root.gotoAndPlay("start");
}
moodleService.init();
}

So that you get :

onClipEvent (load) {
// first request username
//this._visible = false;
_root.firstName = "default";

moodleService.XonInit=function()
{
_root.firstName = moodleService.userFirstName;
_root.dreams =moodleService.oldanswer;
_root.gotoAndPlay("start");
}
moodleService.init();
moodleDebugger.addText('Saving');
}

Don't forget to remove the X from XonInit.
In reply to Andrew Field

Re: Flash module add-on: Connecting my quizzes to Moodle

by Jamie Pratt -
Another thing to try is to add _root. to every reference to moodleService to help Flash can find the class. Eg. change :

moodleService.onInit=function()  to


_root.moodleService.onInit=function()
In reply to Jamie Pratt

Re: Flash module add-on: Connecting my quizzes to Moodle

by Andrew Field -
Thanks I shall give these a try as soon as I get the chance.  It is so long since I experimented that I think I really need to start again.  shy
In reply to Andrew Field

Re: Flash module add-on: Connecting my quizzes to Moodle

by Andrew Field -
Apologies for the title of this thread too - the quizzes are indeed things that I've created, but when I can get them to connect to Moodle they will be available for anyone to use for free.

Thus we can drop the 'my' from the thread title.
In reply to Andrew Field

Re: Flash module add-on: Connecting my quizzes to Moodle

by Josep M. Fontana -
I'd love to see your quizzes for the flash module. It is a little sad that there are not more flash movies available to use with this great module. This module has such great potential and it is (apparently) so underused. So far I think the only movies that are publicly available are the ones Jamie made for us and for Tim Takemoto.  It would be nice if more people shared their flash movies so that other people could use them.

Josep M.