AMFPHP

Jump to: navigation, search
Warning: This page is no longer in use. The information contained on the page should NOT be seen as relevant or reliable.
AMFPHP in Moodle

What is AMFPHP?

AMFPHP is a widely used OS remoting server that allows your Flash movies to send and receive data to and from your web server and interact with your PHP scripts. Data to/from PHP is automatically converted into the appropriate Flash variable type and communication is fast because the format data is sent in is compact and is handled efficiently by the Flash player (large XML files can sometimes take time to be processed).

AMFPHP 1.9.beta

AMFPHP is now in version 1.9.beta (30th September 2008). It is fully compatible with AMF0, Flash 6,7 and 8 ActionScript 2.0, and now with AMF3, Flash 9 ActionScript 3.0. Interfacing with AMFPHP using ActionScript 3.0 has a couple of advantages.

  • There are no ActionScript classes to download and install - Flash CS3 and Flex come with all the remoting classes you need as standard.
  • AMF3 is compressed, meaning it is impressively fast and can now outperform other RPC methods.

AMFPHP for Flash/Flex ActionScript 3.0

If you want to develop applications and services for ActionScript 3.0 using Flash or the Flex framework, please check this page: AMF Moodle

Using AMFPHP with Moodle

  • I downloaded AMFPHP 1.2.6 get it here and installed it in my moodle site under MOODLEROOT/lib/amfphp/ So that gateway.php is at MOODLEROOT/lib/amfphp/gateway.php
  • In gateway.php I :
    • added
      include_once "../../config.php";
      to the beginning of the file.
    • I edited the call to
      $gateway->setBaseClassPath
      so it reads
      $gateway->setBaseClassPath($CFG->libdir."/amfphp/services/");

Installing Flash Remoting Components in Your Flash Editor

Please note: Flash Player 9+ does not require any additional classes or components for Flash Remoting (AMF3). Actionscript 3.0 has all the classes necessary for a fully functioning connection between AMFPHP and Flash clients, i.e. NetConnection and Responder (Adobe AS 3.0 docs).

You must download an extension to the Flash editor here. This installs the necessary code libraries for Flash to communicate with a Flash remoting server. Restart your Flash editor after installing the components. You should then see NetConnection Debugger under the Window menu->Other Panels. If necessary more info can be found on the amfphp site here.

Flash Remoting with Flash CS3

See here for info on using AS2 remoting with Flash CS3. CS3 has remoting built in in AS3 but the examples on this page use AS2.

Testing, testing, 1, 2, 3

Files Created By Steps in this Tutorial

For those who are impatient and don't want to follow these step by step instructions you can find the files created in this tutorial here. Unzip them in lib/amfphp/ and they should automatically install into src and the services directory.

Test service

  • Create a new file under lib/amfphp/services/ called UserName.php
  • Copy and paste the following code :
<?php
class UserName {
    function loggedInAs() {
        global $USER;
        if (isguestuser()){
            return get_string('loggedinasguest', 'moodle');
        }else if (isloggedin()){
            return get_string('loggedinas', 'moodle', fullname($USER));
        } else {
            return get_string('loggedinnot');
        }
    }
}
?>

Notice we are using the Moodle API here (the full Moodle API is available to us!) and also accessing the SESSION data for the currently logged in user in order to fetch their user name. I recommend the use of eclipse for editing your code or vi, you can find info about using both of these editors on Moodle docs and you will find info about browsing the Moodle source code which is the best way to become familiar with the moodle api. In particular see files lib/dmllib.php, lib/moodlelib.php, lib/access.php and possibly lib/weblib.php

  • Open MOODLEROOT/lib/amfphp/browser/ in your browser. You should see UserName listed in the left pane of the service browser.
  • Hit 'mt' to automatically generate code for a method table to tell AMFPHP what methods are available in your class and their access level. The generated code will look like this :
$this->methodTable = array(
	"loggedInAs" => array(
		"description" => "No description given.",
		"arguments" => array(),
		"access" => "private"
	)
);
  • As the service browser says we must copy and paste this code into the constructor of our service class. Our service class code will look like this after adding a constructor function and editing the automatically generated method table :
<?php
class UserName {
    function UserName(){
        $this->methodTable = array(
        "loggedInAs" => array(
            "description" => "Returns string indicating whether user is logged in.",
            "arguments" => array(),
            "access" => "remote"
            )
        );
    }
    function loggedInAs() {
        global $USER;
        if (isguestuser()){
            return get_string('loggedinasguest', 'moodle');
        }else if (isloggedin()){
            return get_string('loggedinas', 'moodle', fullname($USER));
        } else {
            return get_string('loggedinnot');
        }
    }
}
?>

Test Movie

To create a test movie that will access this service function then :

  • open the Flash IDE.
  • make sure you have installed the remoting extensions as detailed as above.
  • add a 'dynamic' text box with instance name 'displaytext' to the stage on Frame 1.
  • open the service browser at MOODLEROOT/lib/amfphp/browser/ and click on 'code'
  • in the text box at the bottom of the page enter UserName and then press 'Save to Disk'. If this doesn't work it is because your web server does not have write access to write to the directory, instead you can copy and paste the code into an editor and save it as MOODLEROOT/lib/src/UserName/UserName.as
  • edit the code in MOODLEROOT/lib/src/UserName/UserName.as and you need to tell the service what to do when Moodle returns it's results. Replace the handleLoggedInAs function with :
	function handleLoggedInAs(re:ResultEvent)
	{
		_root.displaytext.text = re.result;
	}
  • Copy and paste this code onto frame 1.
un = new UserName();
un.loggedInAs();

Now from Control / Debug Movie you can open the movie in debug mode, press the green play button to start the movie (it will be paused initially) and you will see 'Please wait..' and then, 'You are not logged in.'

In your web browser you can open up MOODLEROOT/lib/amfphp/src/UserName/UserName.swf If you are logged into Moodle in that web browser you will see who you are logged in as. If there is a Moodle sesssion, the sesssion info is available to your service code in just the same way that it is in in a php script that generates html.

Flash IDE built in panels

Don't waste too much time with the built in panels in the IDE - the NetConnection debugger and the Service Browser. The NetConnection debugger doesn't seem to work reliably and the service browser is not necessary amfphp has one built in which will work better for you. For debugging services use plenty of trace statements in Flash.

A Second Service and Movie To View And Set Preferences for a User

Create a new fla called User.fla, a copy of UserName.fla. And edit the following on the stage :

  • Move the textbox to the top of the stage and rename it loggedinas
  • add some static text 'User Preferences :' below the text box
  • drag and drop a 'List' component from the 'Components' panel (from the UI section) onto the stage.
  • manually resize the list box to fill the available stage space by dragging the sides of the component.
  • name the list component settings.
  • add another text box and change it to an input text box with instance name 'setting'
  • add a button with instance name 'save'.

Then your stage should look something like this :

amfphpstage.jpg

frame 1 code

Put the following code on frame 1 of the movie :

user = new User();
user.loggedInAs();
user.configSettings();
lo = new Object();
lo.change = function(evt){
    //user.getConfigSetting(evt.target.value);
	user.getConfigSetting(evt.target.value);
}
settings.addEventListener("change", lo);
save.label = 'Save';
buttonlo = new Object();
buttonlo.click = function(evt){
    //user.getConfigSetting(evt.target.value);
	user.setConfigSetting(_root.settings.value, _root.setting.text);
}
save.addEventListener("click", buttonlo);

User.as code

And save the following code in User.as in the same directory as User.fla

import mx.remoting.*;
import mx.rpc.*;
import mx.utils.Delegate;
import mx.remoting.debug.NetDebug;

class User
{
	//Change the gateway URL as needed
	private var gatewayUrl:String = "***MOODLEROOT***/lib/amfphp/gateway.php";
	private var service:Service;

	function User()
	{
		NetDebug.initialize();
		this.service = new Service(this.gatewayUrl, null, "User");
		
	}
	
		
	//Returns string indicating whether a user is logged in.	
	function loggedInAs()
	{
		var pc:PendingCall = service.loggedInAs();
		pc.responder = new RelayResponder(this, "handleLoggedInAs", "handleRemotingError");
		_root.loggedinas.text = 'Loading...';
	}
		
	//Returns an array of config settings you can set. Not accessible from Flash.	
	function configSettings()
	{
		var pc:PendingCall = service.configSettings();
		pc.responder = new RelayResponder(this, "handleConfigSettings", "handleRemotingError");
	}
		
	//Returns a value of a config setting.	
	function getConfigSetting(name)
	{
		var pc:PendingCall = service.getConfigSetting(name);
		pc.responder = new RelayResponder(this, "handleGetConfigSetting", "handleRemotingError");
		_root.setting.text = 'Loading...';
	}
	//Returns a value of a config setting.	
	function setConfigSetting(name, value)
	{
		var pc:PendingCall = service.setConfigSetting(name, value);
	}
	
	function handleLoggedInAs(re:ResultEvent)
	{
		_root.loggedinas.text = re.result;
	}
		
	function handleConfigSettings(re:ResultEvent)
	{
		_root.settings.dataProvider = re.result;
		
	}
	
	function handleGetConfigSetting(re:ResultEvent)
	{
		_root.setting.text = re.result;
	}
	
	function handleRemotingError( fault:FaultEvent ):Void 
	{
		NetDebug.trace({level:"None", message:"Error: " + fault.fault.faultstring });
	}
}

Service code

And save the following code in lib/amfphp/services/User.php

<?php
include(AMFPHP_BASE . "util/MethodTable.php");
class User{
    function User(){
        $this->methodTable = MethodTable::create(__FILE__);
    }

    /**
     * Returns string indicating whether a user is logged in.
     * @access remote
     */
    function loggedInAs() {
        global $USER;
        if (isguestuser()){
            return get_string('loggedinasguest', 'moodle');
        }else if (isloggedin()){
            return get_string('loggedinas', 'moodle', fullname($USER));
        } else {
            return get_string('loggedinnot');
        }
    }
    /**
     * Returns an array of config settings you can set.
     * @access remote
     */
    function configSettings() {
        return array_keys(get_user_preferences());

    }
    /**
     * Returns a value of a config setting.
     * @param string name
     * @access remote
     */
    function getConfigSetting($name) {
        $name = clean_param($name, PARAM_ALPHAEXT);
        return get_user_preferences($name);
    }

    /**
     * sets a value of a config setting.
     * @param string name
     * @param string value
     * @access remote
     */
    function setConfigSetting($name, $value) {
        $name = clean_param($name, PARAM_ALPHAEXT);
        $value = clean_param($value, PARAM_NOTAGS);
        return set_user_preference($name, $value);
    }
}
?>

Movie Operation

When you are logged in this movie will list all user preferences for you. User preference names are listed in the list box and when you click on them then the value is displayed in the text box to the right. You can edit the contents of the text box and press 'Save' to save the new value. Be careful what values you save if this is a real production server logged in to a real users account. A screen shot is shown below.

amfphpmovie.jpg

See also