Renamed, document and tested static_config_path / static_object_directory

This commit is contained in:
lukas committed 2026-10-18 17:17:41 +00:00
1 parent 55419acb09
commit c4f5504fdf
4 files changed
+94 -6

No files matched your search

+8 -4
View File
@@ -53,7 +53,7 @@ class ObjectRetriever implements CustomCacheAndLogInterface {
'cache_storage' => null,
'cache_prefix' => 'clobj:',
'cache_ttl' => 60,
'static_config_path' => null,
'static_object_directory' => null,
'auth_ns' => null,
'auth_secret' => null,
'api_base_url' => null,
@@ -66,6 +66,10 @@ class ObjectRetriever implements CustomCacheAndLogInterface {
'permanent_store_scope' => null
], $options);
// Support deprecated name of static_object_directory
if (!isset($this->options['static_object_directory']) && isset($options['static_config_path']))
$this->options['static_object_directory'] = $options['static_config_path'];
// Check object cache configuration
if (isset($this->options['cache_storage'])
&& !($this->options['cache_storage'] instanceof CacheStorageInterface)
@@ -377,14 +381,14 @@ class ObjectRetriever implements CustomCacheAndLogInterface {
return $this->objects[$uriString][1];
}
if (isset($this->options['static_config_path'])) {
$location = realpath($this->options['static_config_path'].DIRECTORY_SEPARATOR.
if (isset($this->options['static_object_directory'])) {
$location = realpath($this->options['static_object_directory'].DIRECTORY_SEPARATOR.
$coid->getHost().str_replace('/', DIRECTORY_SEPARATOR, $coid->getPath())
.DIRECTORY_SEPARATOR.'object.jsonld');
if ($location && file_exists($location)) {
$object = $location;
$this->logInfoWithTime('Fetched <'.$uriString.'> from static configuration.', $ts);
$this->logInfoWithTime('Fetched <'.$uriString.'> from static object directory.', $ts);
}
}
+28 -1
View File
@@ -180,4 +180,31 @@ $retriever = new ObjectRetriever([
]);
```
Unlike `static_config_path`, which reads object descriptions that you provide yourself, the permanent store is filled automatically by the SDK from the Object API.
Unlike the [static object directory](#static-objects), which contains object descriptions that you provide yourself, the permanent store is filled automatically by the SDK from the Object API.
### Static Objects
The static object directory is a mechanism that is mostly intended for testing. It allows you to provide object descriptions yourself, for example as fixtures in your test suite, so that your code can be tested without connecting to CloudObjects Core, or with objects that differ from or do not yet exist in CloudObjects Core. It should usually not be configured in production.
To enable it, set the `static_object_directory` option to a path on the filesystem. Object descriptions are read from `<directory>/<namespace>/<path of COID>/object.jsonld`, which is the same layout used by the fallback and permanent stores. For example, the object `coid://example.com/MyObject` is read from `<directory>/example.com/MyObject/object.jsonld`, and the namespace object `coid://example.com` itself is read from `<directory>/example.com/object.jsonld`. Each file must contain the object description in JSON-LD format, with an `@id` that matches the COID.
```json
{
"@id": "coid://example.com/MyObject",
"http://www.w3.org/2000/01/rdf-schema#label": "My Object"
}
```
The static object directory is consulted before the external cache, the permanent store and the API. Objects that are not found in the directory are retrieved as usual, so you can override only some objects and let the SDK fetch the rest:
```php
use CloudObjects\SDK\ObjectRetriever;
$retriever = new ObjectRetriever([
'static_object_directory' => __DIR__.'/fixtures/objects',
]);
```
Static objects are only used by `getObjectNode()` and the methods built on it; methods that fetch multiple objects from a namespace, such as `fetchAllObjectsInNamespace()`, always use the API. The SDK never writes to the static object directory, so it is not necessary to specify a scope; any COIDs will be considered for the static store.
In earlier versions of the SDK, this option was called `static_config_path`. The old name is deprecated but still supported.
+1 -1
View File
@@ -7,7 +7,7 @@ The `ObjectRetriever` constructor accepts an associative array of options. All o
| `cache_storage` | External cache storage; must implement `Kevinrob\GuzzleCache\Storage\CacheStorageInterface`, `Psr\Cache\CacheItemPoolInterface` or `Psr\SimpleCache\CacheInterface`. See [caching](caching.md). | `null` |
| `cache_prefix` | Prefix for all keys written to the external cache. | `'clobj:'` |
| `cache_ttl` | Number of seconds that object descriptions are cached, both in memory and in the external cache. | `60` |
| `static_config_path` | Path to a directory with static object descriptions, which are used instead of the API. Objects are read from `<path>/<namespace>/<path of COID>/object.jsonld`. | `null` |
| `static_object_directory` | Directory with static object descriptions, which are used instead of the API; mostly useful for testing. Objects are read from `<directory>/<namespace>/<path of COID>/object.jsonld`. Replaces the deprecated `static_config_path`. See [caching](caching.md#static-objects). | `null` |
| `auth_ns` | Hostname of the namespace to authenticate as, e.g. `example.com`. | `null` |
| `auth_secret` | Shared secret between the authenticating namespace and CloudObjects. | `null` |
| `api_base_url` | Base URL of the CloudObjects Core Object API. If not set, `https://od.coid.link/` is used. | `null` |
@@ -366,4 +366,61 @@ class ObjectRetrieverMockTest extends \PHPUnit\Framework\TestCase {
}
}
private function createStaticObjectDirectory() : string {
$directory = $this->createFallbackStoreDirectory();
mkdir($directory.'/cloudobjects.io/Test', 0777, true);
file_put_contents($directory.'/cloudobjects.io/Test/object.jsonld',
'{"@id":"coid://cloudobjects.io/Test","http://www.w3.org/2000/01/rdf-schema#label":"Static"}');
return $directory;
}
public function testStaticObjectDirectoryUsedWithoutContactingAPI() {
$directory = $this->createStaticObjectDirectory();
$this->retriever = new ObjectRetriever([
'static_object_directory' => $directory,
]);
$mock = new MockHandler([ new Response(500) ]);
$this->retriever->setClient(new Client(['handler' => HandlerStack::create($mock)]));
try {
$object = $this->retriever->getObjectNode(new IRI('coid://cloudobjects.io/Test'));
$this->assertEquals('Static', $object->getProperty('http://www.w3.org/2000/01/rdf-schema#label')->getValue());
// The mocked response has not been consumed
$this->assertCount(1, $mock);
} finally {
$this->removeDirectory($directory);
}
}
public function testStaticObjectDirectoryWithDeprecatedOptionName() {
$directory = $this->createStaticObjectDirectory();
$this->retriever = new ObjectRetriever([
'static_config_path' => $directory,
]);
$this->setMockResponse(new Response(500));
try {
$object = $this->retriever->getObjectNode(new IRI('coid://cloudobjects.io/Test'));
$this->assertEquals('Static', $object->getProperty('http://www.w3.org/2000/01/rdf-schema#label')->getValue());
} finally {
$this->removeDirectory($directory);
}
}
public function testStaticObjectDirectoryFallsThroughToAPI() {
$directory = $this->createStaticObjectDirectory();
$this->retriever = new ObjectRetriever([
'static_object_directory' => $directory,
]);
$this->setMockResponse(new Response(200, ['Content-Type' => 'application/ld+json'],
'{"@id":"coid://cloudobjects.io/Other","http://www.w3.org/2000/01/rdf-schema#label":"API"}'));
try {
$object = $this->retriever->getObjectNode(new IRI('coid://cloudobjects.io/Other'));
$this->assertEquals('API', $object->getProperty('http://www.w3.org/2000/01/rdf-schema#label')->getValue());
} finally {
$this->removeDirectory($directory);
}
}
}