<?php

/* This code demonstrates usage of forecasts management on Lokad
 * using webservices : http://www.lokad.com/ws/TimeSeries.asmx
 * 
 * © 2007 Aymeric Augustin
 * Based on work by Saleem Mirza
 * 
 * Distributed under BSD license
 */


/***** global definitions
 */

// change this to your username and password for Lokad
$username = 'gsloover@gmail.com';
$password = 'lokadarg';

if (!$username || !$password)
    die('Please set $username and $password in the source code before executing this file.');

// for testing purposes, it is strongly advised to create an account
// on http://sandbox.lokad.com and change this to $baseURL = 'sandbox.lokad.com'
$baseURL ='www.lokad.com';


/***** how to initialize a soap client
 * to communicate with the webservices using the NuSOAP library
 * see http://sourceforge.net/projects/nusoap/
 */

function createSoapClient ()
{
    require_once dirname(__FILE__).'/lib/nusoap.php';
    global $baseURL;
    $wsdlURL = 'http://' . $baseURL . '/ws/TimeSeries.asmx?wsdl';
    return new soapclient($wsdlURL, 'wsdl');
}


/***** how to perform authentication
 */

// adds authentication to a SOAP client
// returns true if the authentication was successful
function addAuthentication(&$soap, $username, $password)
{
    // username and password are added in an AuthHeader
    $soap->setHeaders("<AuthHeader xmlns=\"lokad.com/ws\"><UserName>$username</UserName><Password>$password</Password></AuthHeader>");

    // we check if the authentication was successful
    $result = $soap->call('IsAuthenticated');
    if ($error = $soap->getError()) die($error);
    return ($result["IsAuthenticatedResult"] == 'true');
}


/***** how to create a time-series
 * utility function to create a time-serie with random values
 * one point is created each day, starting on the current day, until the 
 * required length is reached
 */
function makeRandomTimeSerie ($name, $length = 10,
                              $unitName = "", $utcOffset = 0)
{
    $timeValues = array();
    for ($i = 0; $i < $length; $i++)
    {
        $time = mktime(0, 0, 0, date("m"), date("d") + $i, date("Y"));
        $value  = rand();
        $timeValues["TimeValue"][$i] = makeTimeValue($time, $value);
    }

    $timeSerie = array(
        "Name" => $name,
        "UnitName" => $unitName,
        "UtcOffset" => $utcOffset,
        "TimeValues"=>$timeValues
    );
    return $timeSerie;
}


/***** how to create a task
 * Possible values:
 *     aggregator: Sum | Minimum | Maximum | First | Last | Average | Count |
 *                 StandardDeviation | Variance
 *     period: Hour | Day | Week | Month | Quarter | Semester | Year

 */
function makeTask ($name, $aggregator = "Sum", $period = "Day", $pastPeriods = 10, $futurePeriods = 5, $periodStart = "2001-01-01T00:00:00")
{
    $task = array(
        "Name" => $name,
        "Aggregator" => $aggregator,
        "Period" => $period,
        "PastPeriods" => $pastPeriods,
        "FuturePeriods" => $futurePeriods,
        "PeriodStart" => $periodStart
    );
    return $task;
}


/***** tests
 */

$soap = createSoapClient();
/*
// Test 1: Authentication

echo "<h3>Authentication</h3>\n";

// without username/password, authentication will fail
echo "<p><em>Calling IsAuthenticated...</em></p>\n";
$result = $soap->call('IsAuthenticated');
if ($error = $soap->getError()) die($error);
echo "<p>Without password: IsAuthenticated: " . $result["IsAuthenticatedResult"] . "</p>\n";

// add username and password
echo "<p>Adding UserName/Password</p>\n";
addAuthentication($soap, $username, $password);

// now it should work
echo "<p><em>Calling IsAuthenticated...</em></p>\n";
$result = $soap->call('IsAuthenticated');
if ($error = $soap->getError()) die($error);
echo "<p>With password: IsAuthenticated: " . $result["IsAuthenticatedResult"] . "</p>\n";

*/
// Test 2: Time-series operations

echo "<h3>Time-series operations</h3>\n";

// obtain the list of all time series
echo "<p><em>Calling GetAllSerieNames...</em></p>\n";
$result = $soap->call('GetAllSerieNames');
if ($error = $soap->getError()) die($error);
// format and display the result
$series = toArray($result['GetAllSerieNamesResult']['string']);
echo "<p>Here is the list of your time-series:</p>\n";
echo "<ul>";
foreach ($series as $key => $name)
    echo "<li>" . $name . "</li>";
echo "</ul>\n";

// create a random time-serie that will be added
$serieName = 'TestSerie' . rand();
$timeSerie = makeRandomTimeSerie($serieName);
// add the time-serie
echo "<p><em>Calling AddSerie...</em></p>\n";
$parameters = array();
$parameters['parameters']['serie'] = $timeSerie;
$result = $soap->call('AddSerie', $parameters);
if($error = $soap->getError()) die($error);
echo "<p>Time-serie $serieName was added successfully.</p>\n";


// Test 3: Forecasting tasks operations : listing, adding and removing

echo "<h3>Forecasting tasks operations</h3>\n";

// create a prediction task for that serie
echo "<p><em>Calling AddTask...</em></p>\n";
$taskName = 'TestTask' . rand();
$task = makeTask($taskName);
// add the task
$parameters = array();
$parameters['parameters']['serieName'] = $serieName;
$parameters['parameters']['task'] = $task;
$result = $soap->call('AddTask', $parameters);
if($error = $soap->getError()) die($error);
echo "<p>Task $taskName was added successfully.</p>\n";


// Test 4: Retreiving forecasts

echo "<h3>Retreiving forecasts</h3>\n";

// retrieve data from the serie 
echo "<p><em>Calling GetSerie...</em></p>\n";
$parameters = array();
$parameters['parameters']['serieName'] = $serieName;
$result = $soap->call('GetSerie', $parameters);
if($error = $soap->getError()) die($error);
// format and display the data
$data = toArray($result['GetSerieResult']['TimeValues']['TimeValue']);
echo "<p>Here is the data in $serieName:</p>\n";
echo "<table>";
foreach ($data as $key => $timeValue)
    echo "<tr><td>" . $timeValue['!Time'] . "</td><td>" . $timeValue['!Value'] . "</td></tr>";
echo "</table>\n";

// obtain forecast
echo "<p><em>Calling GetForecast...</em></p>\n";
$parameters = array();
$parameters['parameters']['serieName'] = $serieName;
$parameters['parameters']['taskName'] = $taskName;
$result = $soap->call('GetForecast', $parameters);
if($error = $soap->getError()) die($error);
// format and display the forecast
$forecasts = toArray($result['GetForecastResult']['TimeValues']['TimeValue']);
echo "<p>Here is the forecast for this task:</p>\n";
echo "<table>";
foreach ($forecasts as $key => $timeValue)
    echo "<tr><td>" . $timeValue['!Time'] . "</td><td>" . $timeValue['!Value'] . "</td></tr>";
echo "</table>\n";


// Test 5: Cleaning-up

echo "<h3>Cleaning-up</h3>\n";

// delete the task
echo "<p><em>Calling DeleteTask...</em></p>\n";
$parameters = array();
$parameters['parameters']['serieName'] = $serieName;
$parameters['parameters']['taskName'] = $taskName;
$result = $soap->call('DeleteTask', $parameters);
if($error = $soap->getError()) die($error);
echo "<p>Task $taskName was deleted successfully.</p>\n";

// remove the time-serie
echo "<p><em>Calling RemoveSerie...</em></p>\n";
$parameters = array();
$parameters['parameters']['serieName'] = $serieName;
$result = $soap->call('RemoveSerie', $parameters);
if($error = $soap->getError()) die($error);
echo "<p>Time-serie $serieName was removed successfully.</p>\n";


/***** Utility functions
 */

// when there is less than one result, the webservices returns a string
// and not an array; this function makes sure the result is an array
function toArray ($data) {
    if ($data == "")
        return array();
    else if (is_string($data))
        return array($data);
    else
        return $data;
}

// makes a correctly formatted time-value from a timestamp and a value
function makeTimeValue ($timestamp, $value)
{
    return array('Time' => date('Y-m-d\TH:i:s', $timestamp),
                 'Value' => $value);
}

?>
