Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
298 changes: 298 additions & 0 deletions docs/quickstart/analytics/data-api-demo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
<?php

/**
* Copyright (c) 2025 Learnosity, MIT License
*
* Data API Demo - Metadata Headers
* This example demonstrates the metadata headers that are automatically
* included in every Data API request by the SDK.
*/

// - - - - - - Section 1: server-side configuration - - - - - - //

// Setup to load the necessary classes from the example directory
require_once __DIR__ . '/../../../bootstrap.php';

Check warning on line 14 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L14

"require_once" statement detected. File manipulations are discouraged. Concatenating is forbidden.
$config = require_once __DIR__ . '/../config.php'; // Load security keys from config.php

Check warning on line 15 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L15

"require_once" statement detected. File manipulations are discouraged. Concatenating is forbidden.

use LearnositySdk\Request\DataApi;
use LearnositySdk\Request\Init;

// Data API endpoint configuration
$endpoint = 'https://data.learnosity.com/latest/itembank/items';
$action = 'get';

// Public & private security keys required to access Learnosity APIs and data
$consumerKey = $config['consumerKey'];
$consumerSecret = $config['consumerSecret'];

// Security packet
$securityPacket = [
'consumer_key' => $consumerKey,
'domain' => 'localhost'
];

// Request packet
$requestPacket = [
'limit' => 3
];

// Make the Data API request
$dataApi = new DataApi();
$response = $dataApi->request(
$endpoint,
$securityPacket,
$consumerSecret,
$requestPacket,
$action
);

// Get response data
$statusCode = $response->getStatusCode();
$responseBody = $response->getBody();

// Extract metadata from the request packet to show what headers were sent
// The SDK automatically adds metadata to the request packet
$init = new Init('data', $securityPacket, $consumerSecret, $requestPacket, $action, null, null, $endpoint);
$generatedRequest = $init->generate();
$decodedRequest = json_decode($generatedRequest['request'], true);
$metadata = $decodedRequest['meta'] ?? [];

// Extract the metadata values that are sent as headers
$consumerHeader = $metadata['consumer'] ?? 'N/A';
$actionHeader = $metadata['action'] ?? 'N/A';
$sdkVersion = $metadata['sdk']['version'] ?? 'unknown';
$sdkLang = $metadata['sdk']['lang'] ?? 'unknown';
$sdkHeader = isset($metadata['sdk']['lang']) && isset($metadata['sdk']['version'])
? strtoupper($metadata['sdk']['lang']) . ':' . ltrim($metadata['sdk']['version'], 'v')
: 'N/A';

// Format response body for display
$formattedResponse = json_encode(json_decode($responseBody), JSON_PRETTY_PRINT);

?>

<!-- Section 2: Web page content -->
<!DOCTYPE html>
<html>
<head>
<title>Data API Demo - Metadata Headers</title>
<link rel="stylesheet" type="text/css" href="../css/style.css">
<style>
.card {
border: 1px solid #ddd;
border-radius: 8px;
margin: 20px 0;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.card-header {
padding: 15px 20px;
border-bottom: 1px solid #ddd;
border-radius: 8px 8px 0 0;
font-weight: bold;
}
.card-header.bg-primary {
background-color: #007bff;
color: white;
}
.card-header.bg-success {
background-color: #28a745;
color: white;
}
.card-header.bg-info {
background-color: #17a2b8;
color: white;
}
.card-body {
padding: 20px;
}
.table {
width: 100%;
border-collapse: collapse;
margin: 10px 0;
}
.table th,
.table td {
padding: 12px;
text-align: left;
border: 1px solid #ddd;
}
.table th {
background-color: #f8f9fa;
font-weight: bold;
}
.badge {
display: inline-block;
padding: 4px 8px;
border-radius: 4px;
font-size: 14px;
font-weight: bold;
}
.badge.bg-success {
background-color: #28a745;
color: white;
}
.badge.bg-danger {
background-color: #dc3545;
color: white;
}
.alert {
padding: 15px;
margin: 20px 0;
border-radius: 4px;
}
.alert-info {
background-color: #d1ecf1;
border: 1px solid #bee5eb;
color: #0c5460;
}
.alert-warning {
background-color: #fff3cd;
border: 1px solid #ffeaa7;
color: #856404;
}
pre {
background-color: #f8f9fa;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
max-height: 400px;
overflow-y: auto;
}
code {
background-color: #f8f9fa;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
}
pre code {
background-color: transparent;
padding: 0;
}
h1 {
color: #333;
margin-bottom: 10px;
}
h3 {
margin: 0;
}
h4 {
margin-top: 0;
}
ul {
line-height: 1.8;
}
.text-muted {
color: #6c757d;
}
strong {
color: #007bff;
}
</style>
</head>
<body>
<h1>Data API Demo - Metadata Headers</h1>
<p>This page demonstrates the metadata headers that are automatically included in every Data API request.</p>

<!-- Request Information Card -->
<div class="card">
<div class="card-header bg-primary">
<h3>Request Information</h3>
</div>
<div class="card-body">
<table class="table">
<tbody>
<tr>
<th style="width: 30%;">Endpoint</th>
<td><code><?php echo htmlspecialchars($endpoint); ?></code></td>

Check warning on line 206 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L206

Use of echo language construct is discouraged.
</tr>
<tr>
<th>Action</th>
<td><code><?php echo htmlspecialchars($action); ?></code></td>

Check warning on line 210 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L210

Use of echo language construct is discouraged.
</tr>
<tr>
<th>Status Code</th>
<td>
<span class="badge <?php echo $statusCode == 200 ? 'bg-success' : 'bg-danger'; ?>">

Check warning on line 215 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L215

Use of echo language construct is discouraged.
<?php echo htmlspecialchars($statusCode); ?>

Check warning on line 216 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L216

Use of echo language construct is discouraged.
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>

<!-- Metadata Headers Card -->
<div class="card">
<div class="card-header bg-success">
<h3>Metadata Headers (Sent Automatically)</h3>
</div>
<div class="card-body">
<p class="text-muted">These headers are added automatically by the SDK and are invisible to customers:</p>
<table class="table">
<thead>
<tr>
<th style="width: 40%;">Header Name</th>
<th>Header Value</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>X-Learnosity-Consumer</code></td>
<td><strong><?php echo htmlspecialchars($consumerHeader); ?></strong></td>

Check warning on line 242 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L242

Use of echo language construct is discouraged.
</tr>
<tr>
<td><code>X-Learnosity-Action</code></td>
<td><strong><?php echo htmlspecialchars($actionHeader); ?></strong></td>

Check warning on line 246 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L246

Use of echo language construct is discouraged.
</tr>
<tr>
<td><code>X-Learnosity-SDK</code></td>
<td><strong><?php echo htmlspecialchars($sdkHeader); ?></strong></td>

Check warning on line 250 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L250

Use of echo language construct is discouraged.
</tr>
</tbody>
</table>
<div class="alert alert-info">
<strong>Metadata Format:</strong>
<ul style="margin-bottom: 0;">
<li><strong>Consumer:</strong> The consumer key from the security packet</li>
<li><strong>Action:</strong> Format is <code>{method}_{endpoint}</code> (e.g., <code><?php echo htmlspecialchars($actionHeader); ?></code>)</li>

Check warning on line 258 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L258

Use of echo language construct is discouraged.
<li><strong>SDK:</strong> Format is <code>{language}:{version}</code> (e.g., <code><?php echo htmlspecialchars($sdkHeader); ?></code>)</li>

Check warning on line 259 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L259

Use of echo language construct is discouraged.
</ul>
</div>
<div class="alert alert-info">
<strong>SDK Metadata (in request packet):</strong>
<ul style="margin-bottom: 0;">
<li><strong>Version:</strong> <code><?php echo htmlspecialchars($sdkVersion); ?></code></li>

Check warning on line 265 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L265

Use of echo language construct is discouraged.
<li><strong>Language:</strong> <code><?php echo htmlspecialchars($sdkLang); ?></code></li>

Check warning on line 266 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L266

Use of echo language construct is discouraged.
<li><strong>Language Version:</strong> <code><?php echo htmlspecialchars($metadata['sdk']['lang_version'] ?? 'N/A'); ?></code></li>

Check warning on line 267 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L267

Use of echo language construct is discouraged.
<li><strong>Platform:</strong> <code><?php echo htmlspecialchars($metadata['sdk']['platform'] ?? 'N/A'); ?></code></li>

Check warning on line 268 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L268

Use of echo language construct is discouraged.
</ul>
</div>
</div>
</div>

<!-- Response Body Card -->
<div class="card">
<div class="card-header bg-info">
<h3>Response Body</h3>
</div>
<div class="card-body">
<pre><code><?php echo htmlspecialchars($formattedResponse); ?></code></pre>

Check warning on line 280 in docs/quickstart/analytics/data-api-demo.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/quickstart/analytics/data-api-demo.php#L280

Use of echo language construct is discouraged.
</div>
</div>

<!-- How It Works Card -->
<div class="alert alert-warning">
<h4>How It Works</h4>
<ul>
<li>The SDK automatically extracts the consumer key from the security packet</li>
<li>The SDK builds the action metadata by combining the HTTP method with the endpoint path</li>
<li>The SDK includes version information from the SDK version file</li>
<li>These values are added as HTTP headers (<code>X-Learnosity-Consumer</code> and <code>X-Learnosity-Action</code>)</li>
<li>The headers are available at the ALB layer for routing decisions</li>
<li>No changes are required to customer code - it's completely transparent!</li>
</ul>
</div>
</body>
</html>

4 changes: 4 additions & 0 deletions docs/quickstart/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ <h3><i class="li-reportsapi hero-icon"></i> Analytics examples</h3>
<li>
<a href="analytics/init_data.php">Paginated data extraction</a>
<p>Example of how to work with large datasets in Data API that return paginated results. <a href="https://github.com/Learnosity/learnosity-sdk-php/blob/master/REFERENCE.md">Learn more</a>.</p>
</li>
<li>
<a href="analytics/data-api-demo.php">Data API metadata headers</a>
<p>Demonstrates the metadata headers that are automatically included in every Data API request by the SDK.</p>
</li>
</ul>

Expand Down
3 changes: 2 additions & 1 deletion src/Request/Init.php
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,8 @@ private function deriveAction(): string

// Remove version information from the path
// (e.g., /v2023.1.lts/itembank/items -> /itembank/items, /v1/sessions -> /sessions, /developer/items -> /items)
$path = preg_replace('/\/(v\d+(\.\d+)*(\.[a-zA-Z]+)?|latest(-lts)?|developer)/', '', $path);
// Supports: v1, v1.85.0, v2023.1.lts, v2025.3.LTS, v2022.3.preview1, latest, latest-lts, developer
$path = preg_replace('/\/(v\d+(\.\d+)*(\.[a-zA-Z0-9]+)?|latest(-lts)?|developer)/', '', $path);

// Ensure path starts with /
if (!empty($path) && $path[0] !== '/') {
Expand Down
9 changes: 9 additions & 0 deletions src/Request/Remote.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,15 @@ private function addMetadataHeaders(array $headers, array $post): array
if (isset($meta['action'])) {
$headers[] = 'X-Learnosity-Action: ' . $meta['action'];
}

// Add SDK header if available (format: language:version, e.g., "PHP:1.1.0")
if (isset($meta['sdk']['lang']) && isset($meta['sdk']['version'])) {
$lang = strtoupper($meta['sdk']['lang']);
$version = $meta['sdk']['version'];
// Remove 'v' prefix if present
$version = ltrim($version, 'v');
$headers[] = 'X-Learnosity-SDK: ' . $lang . ':' . $version;
}
} catch (Exception $e) {
// Silently ignore JSON decode errors to avoid breaking requests
}
Expand Down
Loading