LOM-CH Descriptions¶
A description is a piece of data following the LOM-CH standard. The LOM-CH standard is a superset of the international LOM standard. LOM stands for Learning Object Metadata. It is a standard for representing learning resources, be it books, videos, websites, games, etc. The dsb (Digitale Schulbibliothek) groups many of these descriptions in a large catalog, with an API for searching for descriptions, loading a full description, or even adding new ones.
All communication with the API regarding descriptions requires prior authentication. See Authentication for more information.
Searching descriptions¶
Full text search¶
It is possible to search for description in a variety of ways. The most obvious is doing a full text search:
use Educa\DSB\Client\ApiClient\ClientV2;
use Educa\DSB\Client\ApiClient\ClientAuthenticationException;
use Educa\DSB\Client\ApiClient\ClientRequestException;
$client = new ClientV2('https://dsb-api.educa.ch/v2', 'user@site.com', '/path/to/privatekey.pem', 'passphrase');
try {
$searchResult = $client->authenticate()->search('Cookies');
} catch(ClientRequestException $e) {
// The request failed.
} catch(ClientAuthenticationException $e) {
// The authentication failed.
}
This will do a full text search on the word Cookies. All descriptions that fit the bill are returned by the API in JSON. The client will convert this JSON to an associative array before returning it. The returned value has 3 keys:
- numFound: The number total number of results the API found. This could be more than the number of actual results returned (defaults to 50).
- result: An array of descriptions, the actual search results.
- facets: A tree of facet data. More on this later. By default, this is empty.
You can get this data like so:
// Fetch the descriptions.
$descriptions = $searchResult['result'];
By default, each description has the following properties:
- lomId: The description identifier.
- title: The title of the description.
- teaser: A shorter version of the description body text.
- previewImage: An image representing the learning resource.
Other fields can be added if required. More below.
Adding facets¶
The API supports something called Faceted Search. Simply put, this allows a search engine to dynamically tell what kind of filtering would be possible for the returned results. This information is then usually used to display some sort of list of options (like checkboxes) which can be displayed on a search form to allow dynamic filtering of the results.
By default, no facets are active, but you can ask the API to compute facets for the current query:
use Educa\DSB\Client\ApiClient\ClientV2;
use Educa\DSB\Client\ApiClient\ClientAuthenticationException;
use Educa\DSB\Client\ApiClient\ClientRequestException;
$client = new ClientV2('https://dsb-api.educa.ch/v2', 'user@site.com', '/path/to/privatekey.pem', 'passphrase');
try {
$searchResult = $client->authenticate()->search('Cookies', ['learningResourceType']);
} catch(ClientRequestException $e) {
// The request failed.
} catch(ClientAuthenticationException $e) {
// The authentication failed.
}
This will compute a list of resource types (text, image, website, etc) that are available for all found results. You may use this information to build a search form, and display these facets as checkboxes. The values of these checkboxes can then be used as filters (more below).
It is possible to pass more than one facet to the Client:
use Educa\DSB\Client\ApiClient\ClientV2;
use Educa\DSB\Client\ApiClient\ClientAuthenticationException;
use Educa\DSB\Client\ApiClient\ClientRequestException;
$client = new ClientV2('https://dsb-api.educa.ch/v2', 'user@site.com', '/path/to/privatekey.pem', 'passphrase');
try {
$searchResult = $client->authenticate()->search('Cookies', ['learningResourceType', 'educaSchoolLevels']);
} catch(ClientRequestException $e) {
// The request failed.
} catch(ClientAuthenticationException $e) {
// The authentication failed.
}
A full list of available facets can be found here. A live-example of how these facets can be used can be found here.
Filtering results¶
It is possible to add filters to narrow the search down. This is often closely related to facets (see above). A filter is an object, where each property name is a filter name, and its value is an array of possible values. For example, imagine we only want descriptions in German:
use Educa\DSB\Client\ApiClient\ClientV2;
use Educa\DSB\Client\ApiClient\ClientAuthenticationException;
use Educa\DSB\Client\ApiClient\ClientRequestException;
$client = new ClientV2('https://dsb-api.educa.ch/v2', 'user@site.com', '/path/to/privatekey.pem', 'passphrase');
try {
$searchResult = $client->authenticate()->search('Cookies', [], ['language' => ['de']]);
} catch(ClientRequestException $e) {
// The request failed.
} catch(ClientAuthenticationException $e) {
// The authentication failed.
}
This will filter all results and only show ones in German. Multi-value filters are possible as well. Multiple values are treated as OR, not AND:
use Educa\DSB\Client\ApiClient\ClientV2;
use Educa\DSB\Client\ApiClient\ClientAuthenticationException;
use Educa\DSB\Client\ApiClient\ClientRequestException;
$client = new ClientV2('https://dsb-api.educa.ch/v2', 'user@site.com', '/path/to/privatekey.pem', 'passphrase');
try {
$searchResult = $client->authenticate()->search('Cookies', [], ['learningResourceType' => ['text', 'image']]);
} catch(ClientRequestException $e) {
// The request failed.
} catch(ClientAuthenticationException $e) {
// The authentication failed.
}
This will filter by descriptions that are either text-based or image-based (or both).
Additional fields¶
It is possible to add more fields to the search results. The 4th parameters passed to the client class when searching allows you to specify what more fields should be returned for each search result. For example, the following would add the language
and version
properties to the result:
use Educa\DSB\Client\ApiClient\ClientV2;
use Educa\DSB\Client\ApiClient\ClientAuthenticationException;
use Educa\DSB\Client\ApiClient\ClientRequestException;
$client = new ClientV2('https://dsb-api.educa.ch/v2', 'user@site.com', '/path/to/privatekey.pem', 'passphrase');
try {
$searchResult = $client->authenticate()->search('Cookies', [], [], ['language', 'version']);
} catch(ClientRequestException $e) {
// The request failed.
} catch(ClientAuthenticationException $e) {
// The authentication failed.
}
Read the API documentation for more information.
Pagination and limiting the number of results¶
It is possible to offset the results, effectively giving applications a way to support pagination. The offset is the 5th parameter, and represents by how many items the results should be offset (usually a multiple of the 6th parameter, limit; more below). The following will show results 21 to 70 (50 being the default limit):
use Educa\DSB\Client\ApiClient\ClientV2;
use Educa\DSB\Client\ApiClient\ClientAuthenticationException;
use Educa\DSB\Client\ApiClient\ClientRequestException;
$client = new ClientV2('https://dsb-api.educa.ch/v2', 'user@site.com', '/path/to/privatekey.pem', 'passphrase');
try {
$searchResult = $client->authenticate()->search('Cookies', [], [], [], 20);
} catch(ClientRequestException $e) {
// The request failed.
} catch(ClientAuthenticationException $e) {
// The authentication failed.
}
It is also possible to limit the number of results. The following will only show 20 results (instead of 50, the default):
use Educa\DSB\Client\ApiClient\ClientV2;
use Educa\DSB\Client\ApiClient\ClientAuthenticationException;
use Educa\DSB\Client\ApiClient\ClientRequestException;
$client = new ClientV2('https://dsb-api.educa.ch/v2', 'user@site.com', '/path/to/privatekey.pem', 'passphrase');
try {
$searchResult = $client->authenticate()->search('Cookies', [], [], [], 0, 20);
} catch(ClientRequestException $e) {
// The request failed.
} catch(ClientAuthenticationException $e) {
// The authentication failed.
}
Manipulating results¶
Manipulating this search data might prove cumbersome. This is why there is a special class, called LomDescriptionSearchResult
, which can greatly simplify displaying search results. Simply pass the JSON-decoded value to the constructor:
use Educa\DSB\Client\ApiClient\ClientV2;
use Educa\DSB\Client\ApiClient\ClientAuthenticationException;
use Educa\DSB\Client\ApiClient\ClientRequestException;
use Educa\DSB\Client\Lom\LomDescriptionSearchResult;
$client = new ClientV2('https://dsb-api.educa.ch/v2', 'user@site.com', '/path/to/privatekey.pem', 'passphrase');
try {
$searchResult = $client->authenticate()->search('Cookies', [], [], ['language', 'version']);
} catch(ClientRequestException $e) {
// The request failed.
} catch(ClientAuthenticationException $e) {
// The authentication failed.
}
foreach($searchResult['result'] as $lomData) {
$lomDescription = new LomDescriptionSearchResult($lomData);
echo $lomDescription->getTitle();
echo $lomDescription->getTeaser();
echo $lomDescription->getLomId();
echo $lomDescription->getPreviewImage();
}
For additional fields, like language
and version
in our example, you may use the method getField()
. This method takes a field name as a parameter:
foreach($searchResult['result'] as $lomData) {
$lomDescription = new LomDescriptionSearchResult($lomData);
echo $lomDescription->getField('language');
echo $lomDescription->getField('version');
}
Of course, this also works for the default fields:
foreach($searchResult['result'] as $lomData) {
$lomDescription = new LomDescriptionSearchResult($lomData);
echo $lomDescription->getField('title');
echo $lomDescription->getField('teaser');
echo $lomDescription->getField('lomId');
echo $lomDescription->getField('previewImage');
}
Loading a description¶
It is possible to load the full data for a resource. This will contain all meta-data, as well as data from the Ontology server.
Ontology data¶
Ontology data provides human-readable strings for vocabulary entries. For example, a description can have several contributors. Each of these contributors has a role, like author, editor, etc. These are machine-readable names, and are always the same, regardless of which language the description is in. In order to keep the human-readable values, as well as translations, of these vocabulary entries centralized, one can query the Ontology Server. This can be done directly through the API. See Ontology data for more information. However, the API “injects” most if this data directly into the loaded descriptions, which saves us the hassle.
Multilingual descriptions¶
Because this is communicating with the Swiss national catalog (which has 4 official languages), many descriptions are multilingual. When loading a description, many fields, like title, keyword, etc, can have different values, one per language.
Loading a description¶
Loading a description requires knowing its LOM identifier. This is a UUID, or a MD5 hash prefixed with archibald### for older versions.
use Educa\DSB\Client\ApiClient\ClientV2;
use Educa\DSB\Client\ApiClient\ClientAuthenticationException;
use Educa\DSB\Client\ApiClient\ClientRequestException;
$client = new ClientV2('https://dsb-api.educa.ch/v2', 'user@site.com', '/path/to/privatekey.pem', 'passphrase');
try {
$descriptionData = $client->authenticate()->loadDescription('asd89iowqe-sadjqw98-asd87a9doiiuowqe');
} catch(ClientRequestException $e) {
// The request failed.
} catch(ClientAuthenticationException $e) {
// The authentication failed.
}
This loads the description data as an associative array into $descriptionData
. Look at the API documentation for more information on this data structure.
Manipulating a description¶
This object can be pretty hard to manipulate. That is where LomDescription
comes in. The LomDescription
class can take a JSON-decoded LOM-CH data object and expose its properties in a much more convenient way:
use Educa\DSB\Client\ApiClient\ClientV2;
use Educa\DSB\Client\ApiClient\ClientAuthenticationException;
use Educa\DSB\Client\ApiClient\ClientRequestException;
use Educa\DSB\Client\Lom\LomDescription;
$client = new ClientV2('https://dsb-api.educa.ch/v2', 'user@site.com', '/path/to/privatekey.pem', 'passphrase');
$client = new ClientV2('https://dsb-api.educa.ch/v2', 'user@site.com', '/path/to/privatekey.pem', 'passphrase');
try {
$descriptionData = $client->authenticate()->loadDescription('asd89iowqe-sadjqw98-asd87a9doiiuowqe');
} catch(ClientRequestException $e) {
// The request failed.
} catch(ClientAuthenticationException $e) {
// The authentication failed.
}
$lomDescription = new LomDescription($descriptionData);
echo $lomDescription->getTitle();
echo $lomDescription->getDescription();
echo $lomDescription->getLomId();
echo $lomDescription->getPreviewImage();
Fields that contain data in multiple languages can be instructed to return the information in one language only by specifying a language fallback array. The first language that matches will be returned. If no match is found, the field will be returned in “raw” format (meaning, multilingual fields will be returned as an associative array, with field values keyed by language).
// This will first look for a German title, then fallback to French and
// finally Italian.
echo $lomDescription->getTitle(['de', 'fr', 'it']);
// This will look for French first and fallback to English.
echo $lomDescription->getDescription(['fr', 'en']);
Not all fields have shortcut methods. For fields that the LomDescriptionInterface
interface does not define shortcuts for, you can use the getField()
method. For nested fields, use a dot (.
) notation:
echo $lomDescription->getField('lomId');
// Use a dot (.) notation to fetch nested fields.
echo $lomDescription->getField('lifeCycle.version');
// Fields that are arrays can use numeric field names to get specific items.
echo $lomDescription->getField('technical.keyword.0');
// Fields that are multilingual can use a language fallback array as the
// second parameter.
echo $lomDescription->getField('general.title', ['de', 'fr']);
Creating a new description¶
todo
Updating a description¶
todo
Validating a description¶
It is possible to validate a description to check if no mandatory fields are missing, that they are well formed and respect the LOM-CH standard. Look at the API documentation for more information on this data structure.
Simple validation script:
$client = new ClientV2('https://dsb-api.educa.ch/v2', 'user@site.com', '/path/to/privatekey.pem', 'passphrase');
// Load a json file containing the LOM object
$f = 'lom_object.json';
try {
$json = file_get_contents($f);
$result = $client->authenticate()->validateDescription($json);
echo "Using file $f\n";
if (!empty($response['valid'])) {
echo "\n> Description is valid.";
} else {
echo "\n> Description is invalid.\n";
echo "\nServer response:\n";
echo "==============================\n";
print_r($response);
echo "==============================\n";
}
} catch(ClientRequestException $e) {
// The request failed.
print "The post request failed. (" . $e->getMessage() . ')';
} catch(ClientAuthenticationException $e) {
// The authentication failed.
print "The authentification failed. (" . $e->getMessage() . ')';
}
echo "\n";
Response syntax¶
The response will always contain a valid
key, which is a boolean.
If the submitted LOM object is invalid, the errors
key will be populated with a list of issues.
In case of an invalid LOM object, the API will return:
{"valid":false,"message":"Description is not complete or not compliant.","errors":{"general.identifier":"missing","general.description":"missing","general.language":"missing"}}
The client returns a JSON decoded array:
Array
(
[valid] =>
[message] => Description is not complete or not compliant.
[errors] => Array
(
[general.identifier] => missing
[general.description] => missing
[general.language] => missing
)
)