Search code examples
phpgooddata

GoodData Export Dashboard API


I'm working on how do I export a dashboard from some specific project, like this link shows up.

The code I made, generates the link for download correctly, like expected. But the PDF file exported don't bring the values filtered like I aimed.

My problem happen below this comment:

// Execute the dashboard with context

... where I supose to set "all filters that affects the dashboard", like the link above says. But it does not specify how can I set the value of the filter.

I made all the code in PHP (replace all the "{some-thing}" to make this code work):

<?php 

    $login = '{email}';
    $pass = '{password}';

    $headers = array('accept' => 'Accept: application/json','content-type' => 'Content-Type: application/json; charset=utf-8');
    $data = json_encode(array('postUserLogin'=>array('login'=> $login,'password'=> $pass,'remember'=>0)));

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);     
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_URL, "https://secure.gooddata.com/gdc/account/login");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    $output = curl_exec($ch); 
    $AuthSST =  substr($output, strrpos($output, "GDCAuthSST=")+strlen("GDCAuthSST="), 17);

    $headers = array('accept' => 'Accept: application/json',
                    'content-type' => 'Content-Type: application/json; charset=utf-8', 
                    'cookie:' => 'Cookie: $Version=0; GDCAuthSST='.$AuthSST.' $Path=/gdc/account');

    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_HTTPGET, 1);
    curl_setopt($ch, CURLOPT_URL, "https://secure.gooddata.com/gdc/account/token");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    $output = curl_exec($ch);         

    $start = strrpos($output, "GDCAuthTT=")+strlen("GDCAuthTT=");
    $finish = strrpos($output, "Path=/gdc");

    $GDCAuthTT =  substr($output, $start, ($finish-$start));

    $headers = array('accept' => 'Accept: application/json',
                    'content-type' => 'Content-Type: application/json; charset=utf-8', 
                    'cookie:' => 'Cookie: $Version=0; GDCAuthTT='.$GDCAuthTT.' $Path=/gdc/account');

    // Authentication finished, now start the dashboard export API

    // Execute the dashboard with context

    $project_id = '{project_id}';
    $filter_id = '{filter_id}';
    $filter_obj = '{0000}';
    $dash_obj = '{0000}';
    $url = 'https://secure.gooddata.com/gdc/internal/projects/'.$project_id.'/executionContexts';

    //  Inside filters: constraint, promptUri, uri, id ||||||||| Inside executionContext: dashboard, links, name, type, user

    $bode = json_encode(array('executionContext' => array('filters' => array(array(
                            'uri' => '/gdc/md/'.$project_id.'/obj/'.$filter_obj, // /elements?id=0000
                            'id' => $filter_id)), 
                            'dashboard' => '/gdc/md/'.$project_id.'/obj/'.$dash_obj,
                            'type' => 'export'
                        )));

    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $bode);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    $output = curl_exec($ch);

    // Export the Dashboard

    $dash_tab = 'ae2b1ab3a87c';

    $start = strrpos($output, "\"uri\":\"")+7;
    $finish = strrpos($output, "\"}");

    $url = "https://secure.gooddata.com/gdc/projects/".$project_id."/clientexport";

    $request_url = "https://secure.gooddata.com/dashboard.html#";
    $project = "project=/gdc/projects/".$project_id;
    $dashboard = "&dashboard=/gdc/md/".$project_id."/obj/".$dash_obj;
    $tab = "&tab=".$dash_tab."&export=1";
    $ctx = "&ctx=".substr($output, $start, ($finish-$start));

    $bode2 = json_encode(array('clientExport'=>array('url'=>$request_url.$project.$dashboard.$tab.$ctx, 'name'=>'{Dash_Name}')));

    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $bode2);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    $output = curl_exec($ch);

    // Poll the URL from response Result:

    $start = strrpos($output, "\"poll\":\"")+8;
    $finish = strrpos($output, "\"}");
    $poll = "https://secure.gooddata.com".substr($output, $start, ($finish-$start));

    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_HTTPGET, 1);
    curl_setopt($ch, CURLOPT_URL, $poll);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1);

    $output = curl_exec($ch);

    echo "Link: ".$poll;
    echo "<br>Output: ".$output;

    // Wait 90 seconds and then make the download, otherwise it returns 202 http code

    sleep(90);

    $opts = array('http' =>
      array(
        'method'  => 'GET',
        'header'  => "Accept: application/json\r\n".
            "Content-Type: application/json; charset=utf-8\r\n".
          'Cookie: $Version=0; GDCAuthTT='.$GDCAuthTT.' $Path=/gdc/account'."\r\n",
        'timeout' => 6000
      )
    );

    $context  = stream_context_create($opts);
    $file = file_get_contents($poll."?download=true", false, $context);
    file_put_contents("Dashboard.pdf", $file);

    echo "<br><br>Link used: ".$poll."?download=true";

    $errors= error_get_last();
    echo "<br><br>".$errors['type'];
    echo "<br>".$errors['message'];

    curl_close($ch);
?>

Solution

  • You can specify the filter values using constraint object in the filter definition. The exact constraint format depends on the type of the filter. If the filter is type of list the constraint format is:

    "constraint": {
        "type": "list",
        "elements": [
          "/gdc/md/{project_id}/obj/{attribute_id}?id={element_id}",
          ...
        ]
    }
    

    if it is a date filter the constraint looks like:

    "constraint": {
        "from": "2006-07-01",
        "to": "2008-03-31",
        "type": "interval"
    }
    

    or

    "constraint": {
      "from": -5,
      "to": 0,
      "type": "floating"
    }
    

    Example of the whole executionContext object for POST with one list filter with 2 values selected:

    {
      "executionContext": {
        "filters": [
          {
            "uri": "/gdc/md/{project_id}/obj/{attribute_id}",
            "constraint": {
              "type": "list",
              "elements": [
                "/gdc/md/{project_id}/obj/{displayForm_id}/elements?id={element_id_1}",
                "/gdc/md/{project_id}/obj/{displayForm_id}/elements?id={element_id_2}"
              ]
            },
            "id": "{filter_id}"
          }
        ],
        "dashboard": "/gdc/md/{project_id}/obj/{dashboard_id}",
        "type": "export"
      }
    }
    

    You can see the valid example of filter constraint e.g. in the docs for handling drills or creating of saved view.