Skip to content

Commit

Permalink
TemplateMetadata: add PARENT special value and allow some special val…
Browse files Browse the repository at this point in the history
…ues to be used on the right side of if
  • Loading branch information
zozlak committed Sep 16, 2024
1 parent d7469da commit b0145d5
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 22 deletions.
3 changes: 3 additions & 0 deletions doc/TemplateMetadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,9 @@ A term consists of:
* optional operator and value
* operator is one of `==`, `!=`, `starts`, `ends`, `contains`, `>`, `<`, `>=`, `<=`, `regex`
* value is single- or double-quited literal value or an RDF property in the `prefix:suffix` format
or a special value of `OAIID`, `URI`/`URL` (see the `val` attribute documentation)
or a special value of `PARENT` (meaning last direct parent of the previous `foreach`;
if there is no `foreach`, then its equivalent to `URI`/`URL`)

E.g.

Expand Down
60 changes: 38 additions & 22 deletions src/acdhOeaw/arche/oaipmh/metadata/TemplateMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@
*/
class TemplateMetadata implements MetadataInterface {

const PREDICATE_REGEX = '[-_a-zA-Z0-9]+:[^ )]*';
const IF_VALUE_REGEX = '(==|!=|starts|ends|contains|>|<|>=|<=|regex) +(?:"([^"]*)"|\'([^\']*)\'|([0-9]+[.]?[0-9]*)|(' . self::PREDICATE_REGEX . '))';
const PREDICATE_REGEX = '[-_a-zA-Z0-9]+:[^ )]*|CURNODE';
const IF_VALUE_REGEX = '(==|!=|starts|ends|contains|>|<|>=|<=|regex) +(?:"([^"]*)"|\'([^\']*)\'|([0-9]+[.]?[0-9]*)|(' . self::PREDICATE_REGEX . ')|(OAIID|URI|URL|PARENT))';
const IF_PART_REGEX = '`^ *(any|every|none)[(](' . self::PREDICATE_REGEX . ')(?: +' . self::IF_VALUE_REGEX . ')?[)]`u';
const IF_LOGICAL_REGEX = '`^ *(OR|AND|NOT) *`';

Expand All @@ -84,6 +84,19 @@ class TemplateMetadata implements MetadataInterface {
*/
static private array $loadedInverse = [];

static public function extendSearchFilterQuery(MetadataFormat $format): QueryPart {
return new QueryPart();
}

static public function extendSearchDataQuery(MetadataFormat $format): QueryPart {
return new QueryPart();
}

static public function clearDataset(): void {
self::$dataset = new Dataset();
self::$loadedInverse = [];
}

/**
* Repository resource object
*/
Expand Down Expand Up @@ -184,14 +197,6 @@ public function getXml(): DOMElement {
return $this->xml->documentElement;
}

static public function extendSearchFilterQuery(MetadataFormat $format): QueryPart {
return new QueryPart();
}

static public function extendSearchDataQuery(MetadataFormat $format): QueryPart {
return new QueryPart();
}

private function processElement(DOMDocument | DOMElement $el): void {
$this->xmlLocation[] = $el->nodeName;
$this->removeUnneededNodes($el);
Expand Down Expand Up @@ -294,7 +299,13 @@ private function evaluateIf(string $if): bool {
$func = $matches[1];
$value = null;
if (!empty($matches[3])) {
$value = !empty($matches[7]) ? $this->expand($matches[7]) : $matches[4] . ($matches[5] ?? '') . ($matches[6] ?? '');
if (!empty($matches[8])) {
$value = $this->getSpecialValue($matches[8]);
} elseif (!empty($matches[7])) {
$value = $this->expand($matches[7]);
} else {
$value = $matches[4] . ($matches[5] ?? '') . ($matches[6] ?? '');
}
if ($matches[3] === ValueTemplate::REGEX) {
$value = "`$value`u";
}
Expand Down Expand Up @@ -412,17 +423,7 @@ private function processValue(DOMDocument | DOMElement $el): void {
}

private function fetchValues(Value $val): array {
$result = match ($val->path) {
'NOW' => (new DateTimeImmutable())->format(DateTimeImmutable::ISO8601),
'URI', 'URL' => $this->res->getRepo()->getBaseUrl() . $this->headerData->repoid,
'METAURL' => $this->res->getRepo()->getBaseUrl() . $this->headerData->repoid . '/metadata',
'OAIID' => $this->headerData->id,
'OAIURL' => $this->format->info->baseURL . '?verb=GetRecord&metadataPrefix=' . rawurlencode($this->format->metadataPrefix) . '&identifier=' . rawurldecode($this->headerData->id),
'RANDOM' => rand(),
'SEQ' => $this->seqNo++,
'CURNODE' => end($this->nodesStack),
default => null,
};
$result = $this->getSpecialValue($val->path);
if ($result !== null) {
return [$result];
}
Expand Down Expand Up @@ -514,4 +515,19 @@ private function loadMetadata(array $resources,
}
}
}

private function getSpecialValue(string $val): TermInterface | string | null {
return match ($val) {
'NOW' => (new DateTimeImmutable())->format(DateTimeImmutable::ISO8601),
'URI', 'URL' => $this->res->getRepo()->getBaseUrl() . $this->headerData->repoid,
'METAURL' => $this->res->getRepo()->getBaseUrl() . $this->headerData->repoid . '/metadata',
'OAIID' => $this->headerData->id,
'OAIURL' => $this->format->info->baseURL . '?verb=GetRecord&metadataPrefix=' . rawurlencode($this->format->metadataPrefix) . '&identifier=' . rawurldecode($this->headerData->id),
'RANDOM' => rand(),
'SEQ' => $this->seqNo++,
'CURNODE' => end($this->nodesStack),
'PARENT' => $this->nodesStack[count($this->nodesStack) - 2],
default => null,
};
}
}
19 changes: 19 additions & 0 deletions tests/TemplateMetadataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
namespace acdhOeaw\arche\oaipmh\tests;

use DateTimeImmutable;
use acdhOeaw\arche\oaipmh\metadata\TemplateMetadata;

/**
* Description of TemplateMetadataTest
Expand All @@ -35,6 +36,11 @@
*/
class TemplateMetadataTest extends TestBase {

public function setUp(): void {
parent::setUp();
TemplateMetadata::clearDataset();
}

public function testCommentsWhitespaces(): void {
$in = file_get_contents(__DIR__ . '/data/keepComments.xml');
$tmpl = $this->getMetadataObject('common', $in);
Expand Down Expand Up @@ -345,6 +351,19 @@ public function testFetchCycle(): void {
<e>http://127.0.0.1/api/234</e>
<e>http://127.0.0.1/api/345</e>
</root>
OUT;
$this->assertEquals($this->std($expected), $xml);
}

public function testIfSpecial(): void {
$tmpl = $this->getMetadataObject('ifSpecial');
$xml = $this->asString($tmpl->getXml());
$expected = <<<OUT
<root>
<a>foo</a>
<cc1>baz</cc1>
<cc2>baz</cc2>
</root>
OUT;
$this->assertEquals($this->std($expected), $xml);
}
Expand Down
8 changes: 8 additions & 0 deletions tests/data/ifSpecial.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<http://127.0.0.1/api/123> <https://id> <http://127.0.0.1/api/123> ,
<https://foo> ;
<https://next> <http://127.0.0.1/api/124> ,
<http://127.0.0.1/api/234> ;
<https://label> "foo" .
<http://127.0.0.1/api/124> <https://label> "bar" .
<http://127.0.0.1/api/234> <https://label> "baz" ;
<https://parent> <http://127.0.0.1/api/123> .
10 changes: 10 additions & 0 deletions tests/data/ifSpecial.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<root>
<a if="any(base:id == OAIID)" val="/base:label"></a>
<b if="any(base:next == OAIID)" val="/base:label"></b>
<c foreach="/base:next" remove="remove">
<cc1 if="any(base:parent == PARENT)" val="/base:label"/>
<cc2 if="any(base:parent == URI)" val="/base:label"/>
<cc3 if="any(base:parent == OAIID)" val="/base:label"/>
</c>
</root>
10 changes: 10 additions & 0 deletions tests/data/ifSpecial.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
metadataPrefix: templateMetadata
metadataNamespace: http://unknown/namespace
schema: http://unknown/schema
class: \acdhOeaw\arche\oaipmh\metadata\TemplateMetadata
templatePath: ""
keepComments: false
xmlErrors: true
rdfNamespaces:
base: https://
local: http://127.0.0.1/api/

0 comments on commit b0145d5

Please sign in to comment.