Question

I have created a USSD application in PHP, Since USSD requests are unique ( new request for each selection ) I need a way to track them , Track in the sence i need a way to store the flow of the application, In my USSD app there are Static menus as well as Dynamic menus ( Retrieved from the Database ) , My problem is , I have created the app with lots of if, else and switch statements, And It's really difficult to update the menu items. So can anyone suggest me a good algorithm to create this USSD app? I mean a efficient way to tackle the problem, I need a way where I could be able to add and remove menus according the clients request, When I do that , my code shouldn't break. Can anyone help me on this?

-Thanks & Regards

PS: I have read this and this and it doesn't actually answer my question.

Was it helpful?

Solution

The best method working with USSD is making each command a separate class. This way you can work , debug and maintain a large USSD application

Example

$ussd = new USSDMessage(); // USSD Class 

$main = new Command("menu"); // Starting Command 

// Register multiple command 
$main->register(new Command("help"));
$main->register(new Command("account"));
$main->register(new Command("transfer"));
$main->register( new Recharge("reacharge"));

$main->run($ussd); // Run Request 

Basic Class Structure

// Class To receve message from USSD
class USSDMessage {
    function next();
    function saveSession();
}

// Basic Command  Class 
class Command {
    private $name;
    private $cmd = array();

    function __construct($name) {
        $this->name = $name;
    }

    function register(Command $menu) {
        $this->cmd[$menu->getName] = $menu;
    }

    function run(USSDMessage $ussd) {
        $key = $ussd->next(); // get next inpur from ussd

        if (isset($this->cmd[$key])){
            $ussd->run($ussd);
        }
    }
}

// Recharge Command Example 
class Recharge extends Command {

    function run(USSDMessage $ussd) {
        $key = $ussd->next();

        switch ($key){
            case "1":
                // Proccess card recharge
                // Do Somthing 
                $ussd->saveSession(); // End Session 
                break;
            case "2":
                // Process direct deposit
                // Do Somthing
                $ussd->saveSession(); // End Session
                break;
            default:
                // Format Not supported
                // Do Somthing
                $ussd->saveSession(); // End Session
                break;
        }
    }
}

OTHER TIPS

Based on what I got from OP's question, here is some hint:

This problem is related to tree traversal. Each state of the menu will be store at one node of the tree.

If you don't have any knowledge about Suffix tree/trie, read here. The idea is simple, as there is a limited option for user to input: 0,1,2,3,4,5,6...9,#,*, we can represent all the states in one tree.

Each node of the tree will be something like:

Node{        
    Node [] next = new Node[12];//All options from 0 to *
    Menu menu;
}

So instead of if and switch, we can easily locate and store all states by using and traversing through the tree from root to leaf. And to refer to all the states, we only need to store one variable: Node root

For example, if we have a series of action #111#. (Assume that # is at index 10 and * at index 11) We will always begin at root -> go to Node at index 10-> go to Node at index 1 ... and finally, return the menu.

Pseudo code:

Menu traverse(String input){
    Node cur = root;
    for(int index in input){
        cur = cur.next[index];
    }
    return cur.menu;
}

For deleting a state/branch, just traverse from root to that leaf, and replace that leaf node in the parent next array with a null.

Note: You can manage list of menu even more easily if you store all menus in an array Menu[]menu, and for each node, instead of return a Menu, you will return an integer indicates the index of desired menu in the array menu.

You should try to use your DB queries to maintain the state of the application, using the DB queries will help you track the users' progress and also graduate them to the upper levels and demote them to lower levels, that way you can make your life easier in maintaining your code. Take a look at a code snippet below to help you understand session based USSD progress using AfricasTalking platform.

if($userResponse==""){
        // this is when you receive nothing from the user. serve them the registration menu
        switch ($level) {
            case 0:
                //. Graduate the user to the next level, so you dont serve them the same menu
                 $sql1 = "INSERT INTO `some_seesion_name`(`session_id`, `yourIdentifier`,`level`) VALUES('".$sessionId."','".$yourIdentifier."', 1)";
                 $db->query($sql1);

                 // Insert the Identifier, since it comes with the first POST
                 $sql1a = "INSERT INTO YourDB(`yourIdentifier`) VALUES ('".$yourIdentifier."')";
                 $db->query($sql1a);

                 // Serve the menu request for name
                 $response = "CON Please enter your name";

                // Print the response onto the page so that our gateway can read it
                header('Content-type: text/plain');
                echo $response; 
                break;

     // continue the flow of the app ...... 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top