restruct/edudex-api-client

PHP client library for the EDU-DEX Data API. Framework-agnostic with optional SilverStripe integration.

Installs: 3

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/restruct/edudex-api-client

1.0.0 2025-10-09 14:58 UTC

This package is auto-updated.

Last update: 2025-10-10 12:59:17 UTC


README

License: MIT PHP Version

PHP client library for the EDU-DEX Data API. Framework-agnostic with optional SilverStripe integration.

Features

  • 🎯 Complete API Coverage - All endpoints from the EDU-DEX OpenAPI specification
  • 🔌 Framework Agnostic - Works with any PHP 8.1+ project
  • 🔧 Optional SilverStripe Integration - Full Config API, Extensions, and Injector support
  • 🎨 Clean Architecture - PSR-4 autoloading, typed models, endpoint classes
  • 🛡️ Type Safe - PHP 8.1+ with strict type hints and return types
  • 📦 Smart Models - Automatic hydration, serialization, and type casting
  • 🌍 Localization - Built-in LocalizedString helper for multi-language content
  • Validation - Pre-submission validation for programs, metadata, and discounts
  • 🔐 Secure - Bearer token authentication with environment variable support
  • 📝 Well Documented - Comprehensive PHPDoc blocks and usage examples

Installation

Install via Composer:

composer require restruct/edudex-api-client

Quick Start

Basic Usage (Any PHP Project)

<?php
require 'vendor/autoload.php';

use Restruct\EduDex\Client;

// Initialize with bearer token
$client = new Client('your-jwt-bearer-token');

// Or use environment variable EDUDEX_API_TOKEN
$client = new Client();

// Fetch organizations
$organizations = $client->organizations()->list();

foreach ($organizations as $org) {
    echo $org->getLocalizedName('nl') . "\n";
}

Configuration

use Restruct\EduDex\Client;

// From array
$config = [
    'bearer_token' => 'your-token',
    'api_base_url' => 'https://api.edudex.nl/data/v1/',
    'timeout' => 30,
];
$client = Client::fromConfig($config);

// From environment variable
// Set EDUDEX_API_TOKEN in your .env file
$client = new Client();

Usage Examples

Working with Organizations

use Restruct\EduDex\Client;

$client = new Client();

// List all organizations
$organizations = $client->organizations()->list();

// Get specific organization
$org = $client->organizations()->get('organization-id');

echo "Name: " . $org->getLocalizedName('nl') . "\n";
echo "Roles: " . implode(', ', $org->roles) . "\n";
echo "Supplier: " . ($org->isSupplier() ? 'Yes' : 'No') . "\n";

// Working with catalogs
$catalogs = $client->organizations()->listStaticCatalogs('org-id');

foreach ($catalogs as $catalog) {
    echo "{$catalog->title}: {$catalog->countActive}/{$catalog->countTotal} programs\n";
}

Managing Programs

// List programs for a supplier
$programs = $client->suppliers()->listPrograms('supplier-id');

// Get specific program
$program = $client->suppliers()->getProgram('supplier-id', 'program-id', 'client-id');

echo "Title: " . $program->getTitle('nl') . "\n";
echo "Description: " . $program->getDescription('en') . "\n";

// Create or update program
$programData = [
    'editor' => 'Admin User',
    'format' => 'application/vnd.edudex.program+json',
    'generator' => 'My CMS v1.0',
    'lastEdited' => date('c'),
    'programDescriptions' => [
        'title' => ['nl' => 'Cursus Titel', 'en' => 'Course Title'],
    ],
    // ... additional program data
];

$client->suppliers()->upsertProgram('supplier-id', 'program-id', 'client-id', $programData);

Validating Data

// Validate program before submission
$result = $client->validations()->validateProgram($programData);

if ($result->isValid()) {
    echo "✓ Validation passed!\n";

    // Submit the program
    $client->suppliers()->upsertProgram(...);
} else {
    echo "✗ Validation failed:\n";

    foreach ($result->getErrors() as $error) {
        echo "{$error->message}";
        if ($error->contextPath) {
            echo " (at {$error->contextPath})";
        }
        echo "\n";
    }
}

Bulk Operations

// Fetch multiple programs at once
$programsToFetch = [
    ['orgUnitId' => 'supplier-1', 'programId' => 'prog-1', 'clientId' => 'public'],
    ['orgUnitId' => 'supplier-2', 'programId' => 'prog-2', 'clientId' => 'client-1'],
];

$response = $client->programs()->bulk($programsToFetch);

// Process results
$successful = $client->programs()->getSuccessful($response);
$failed = $client->programs()->getFailed($response);

echo "Retrieved " . count($successful) . " programs\n";
echo "Failed: " . count($failed) . " programs\n";

Error Handling

use Restruct\EduDex\Exceptions\AuthenticationException;
use Restruct\EduDex\Exceptions\ValidationException;
use Restruct\EduDex\Exceptions\ApiException;
use Restruct\EduDex\Exceptions\EduDexException;

try {
    $org = $client->organizations()->get('org-id');

} catch (AuthenticationException $e) {
    // Handle 401/403 errors
    echo "Authentication error: {$e->getMessage()}\n";

} catch (ValidationException $e) {
    // Handle validation errors with detailed messages
    foreach ($e->getErrors() as $error) {
        echo "Error: {$error['message']}\n";
    }

} catch (ApiException $e) {
    // Handle other API errors
    echo "API error: {$e->getMessage()}\n";

} catch (EduDexException $e) {
    // Catch-all
    echo "Error: {$e->getMessage()}\n";
}

SilverStripe Integration

For SilverStripe projects, use the optional integration layer:

composer require restruct/edudex-api-client
composer require silverstripe/framework:^5.0

Configuration

Add to app/_config/edudex.yml:

---
Name: app-edudex
---

# SilverStripe Client configuration (optional)
Restruct\EduDex\Integration\SilverStripe\SilverStripeClient:
  api_base_url: 'https://api.edudex.nl/data/v1/'
  timeout: 30

# Configure Injector
SilverStripe\Core\Injector\Injector:
  Restruct\EduDex\Client:
    class: Restruct\EduDex\Integration\SilverStripe\SilverStripeClient

# Add CMS integration
SilverStripe\SiteConfig\SiteConfig:
  extensions:
    - Restruct\EduDex\Integration\SilverStripe\Extensions\SiteConfigExtension

Usage in SilverStripe

use Restruct\EduDex\Integration\SilverStripe\SilverStripeClient;

// Using singleton
$client = SilverStripeClient::singleton();

// Or via Injector
$client = Injector::inst()->get(SilverStripeClient::class);

// Same API as standalone
$organizations = $client->organizations()->list();

See docs/SILVERSTRIPE_INTEGRATION.md for complete documentation.

API Reference

Endpoints

  • Organizations - Manage organizations, catalogs, and webhooks
  • Suppliers - Supplier management, programs, discounts, metadata
  • Accreditors - Accreditor management and accreditations
  • Programs - Bulk program operations
  • Validations - Validate programs, metadata, and discounts

Models

  • Organization - Organization with roles and accreditations
  • Supplier - Training provider
  • Accreditor - Accreditation organization
  • Accreditation - Supplier accreditation with validity
  • StaticCatalog - Manual program catalog
  • DynamicCatalog - Automatic catalog with filters
  • Webhook - Event notification endpoint
  • Program - Training program/course
  • ValidationResult - Validation response

Type Helpers

  • LocalizedString - Multi-language content handler
  • ValidationMessage - Validation message with severity

Exceptions

  • EduDexException - Base exception
  • AuthenticationException - 401/403 errors
  • ValidationException - 400 validation errors
  • ApiException - Other HTTP errors

Documentation

Requirements

  • PHP 8.1 or higher (PHP 7.4 version in backport branch)
  • GuzzleHTTP ^7.0
  • PSR-3 Logger interface

Optional:

  • SilverStripe Framework ^5.0 (for SilverStripe integration)

Testing

# Install dev dependencies
composer install

# Run tests
composer test

# Run static analysis
composer phpstan

# Check code style
composer cs-check

# Fix code style
composer cs-fix

Support

License

This library is open-sourced software licensed under the MIT license.

Credits

  • Michael van Schaik (Restruct.nl) - development
  • Bart van Irsel (Webium) - AI consultant/guru
  • Claude (Anthropic) - AI co-author and code generation
  • EDU-DEX API by WebHare BV