acdh-oeaw/repo-php-util

用于操作我们仓库堆栈的类集

2.28.3 2020-02-18 10:25 UTC

README

用于操作ACDH仓库堆栈的类集。

弃用信息

ACHD已从Fedora Commons切换到ARCHE,这使得这个库变得过时

安装

  • 获取composer (https://getcomposer.org.cn/)
  • 准备包含以下内容的composer.json文件
    {
      "require": {
          "acdh-oeaw/repo-php-util": "*"
      }
    }
    
  • 运行composer install
  • 复制并调整文件
    • vendor/acdh-oeaw/repo-php-util/config.ini.sample (服务URL,凭据,元数据架构基础)
    • vendor/acdh-oeaw/repo-php-util/property_mappings.json (Redmine问题属性映射)

初始化

  • (可选但非常有用) 为配置类声明一个shortcat
  • 加载composer
  • 使用config.ini文件初始化配置
  • 创建acdhOeaw\fedora\Fedora类的对象
use acdhOeaw\util\RepoConfig as RC;

require_once 'vendor/autoload.php';

RC::init('config.ini');
$fedora = new acdhOeaw\fedora\Fedora();

文档

您可以在docs文件夹中找到详细的API文档。

要在线阅读,请访问https://acdh-oeaw.github.io/repo-php-util/

使用方法

(假设您已经运行了初始化代码,特别是创建了$fedora对象)

处理Fedora资源

Fedora资源由achdOeaw\fedora\FedoraResource类表示。

此类为您提供了基本方法来操作资源元数据和二进制内容(请参见下面的示例)。

通常您不应直接创建FedoraResource对象,而应始终使用适当的Fedora类方法(请参见下面的示例)。
如果您想了解更多信息,请阅读Fedora类的文档,特别是关于事务处理的章节。

元数据由EasyRdf Resource对象表示。

在RDF中更新元数据可能会很棘手,所以请阅读下面提供的关于此主题的示例。

所有资源修改都必须在Fedora事务内完成,所以代码示例中的所有$fedora->begin()$fedora->commit()都是必需的。

创建新的Fedora资源

准备资源元数据和(可选)其二进制内容,并调用Fedora类的createResource()方法。

$graph = new EasyRdf\Graph();
$metadata = $graph->resource('.'); // the resource URI you provide here is irrelevant and can be any string (the EasyRdf library requires it to be non-empty)
$metadata->addLiteral('http://my.data/#property', 'myDataPropertyValue');
$metadata->addResource('http://my.object/#property', 'http://my.Object/Property/Value');

$fedora->begin();
$resource1 = $fedora->createResource($metadata, 'pathToFile'); // with binary data from file, at the repository root
$resource2 = $fedora->createResource($metadata, 'myResourceData (...)'); // with binary data from string, at the repository root
$resource3 = $fedora->createResource($metadata); // without binary data, at the repository root
$resource4 = $fedora->createResource($metadata, '', '/my/collection'); // without binary data, as a child of a given Fedora collection (the collection has to exist)
$resource5 = $fedora->createResource($metadata, 'pathToFile', '/my/resource', 'PUT'); // with binary data from file, at a given location (the '/my' collection has to exist)
$fedora->commit();

查找已存在的Fedora资源

如果您知道资源的ACDH ID,可以使用getResourceById()方法。

$resource = $fedora->getResourceById('https://id.acdh.oeaw.ac.at/ba83b0d6-86cd-4340-bfd7-ab5a2edb345a');
echo $resource->__metaToString();

如果您知道资源的元数据属性值,可以使用getResourcesByProperty()方法搜索具有此类值的所有资源。

$resources = $fedora->getResourceByProperty('http://www.w3.org/2000/01/rdf-schema#seeAlso', 'https://redmine.acdh.oeaw.ac.at/issues/5488');
echo count($resources);
echo $resources[0]->__metaToString();

当然,如果您知道资源的Fedora URI,也可以使用它(使用getResourceByUri()方法)。

$resource = $fedora->getResourceByUri('http://fedora.apollo.arz.oeaw.ac.at/rest/92/35/a8/40/9235a840-5f0e-4f24-971d-c0c557f43d9e');
echo $resource->__metaToString();

更新资源元数据

更新RDF元数据可能会很棘手。主要问题是元数据属性值的更新没有明确定义,因此不能为您自动完成。

假设我们有一个现有的元数据三元组<ourResource> <ourProperty> "currentValue"和一个新的三元组<ourResource> <ourProperty> "newValue"
无法自动决定新三元组是替换旧三元组还是将其添加到旁边。
这是因为RDF三元组由其所有组成部分(主题、属性和对象)唯一标识,任何组成部分(包括对象)的变化都会导致新的三元组与之前的形态不匹配。

这意味着避免三元组乘积的唯一方法就是删除以前的元数据并添加所有当前的三元组。
这会由库自动完成,但意味着您在调用setMetadata()方法时必须始终提供完整的元数据集,否则您可能会丢失任何元数据三元组。

请记住

  • 始终以当前资源元数据为基础。
    • 唯一例外可能是在您确信新的三元组当前元数据中不存在且不会干扰当前元数据(基本上旧元数据和新元数据之间没有共同的属性)的情况下。
      在这种情况下,请使用updateMetadata('ADD')方法。
  • 记得在添加当前元数据之前删除所有元数据值(记住,没有更新,只是删除和添加)。
    • 如果属性可以有多个值,请确保您只删除一次(不要为遇到的每个新值重复删除)。
  • 处理rdfs:identifierrdf:isPartOf属性时务必三思(这两个属性非常重要)。

好例子。

$myProperty = 'http://my.new/#property'

$fedora->begin();

$resource = $fedora->getResourcesById('https://redmine.acdh.oeaw.ac.at/issues/5488');
$metadata = $resource->getMetadata();
$metadata->delete($myProperty));
foreach(array('value1', 'value2') as $i){
    $metadata->addLiteral($myProperty, $i);
}
$resource->setMetadata($metadata);
$resource->updateMetadata();

$fedora->commit();

坏例子1。您将最终得到一个只包含您的新三元组的资源。所有其他元数据都将丢失。

$myProperty = 'http://my.new/#property'

$fedora->begin();

$graph = new EasyRdf\Graph();
$metadata = $graph->resource('.');
foreach(array('value1', 'value2') as $i){
    $metadata->addLiteral($myProperty, $i);
}
$resource->setMetadata($metadata);
$resource->updateMetadata();

$fedora->commit();

坏例子2。您将最终得到属性的旧值和新值。

$myExistingProperty = 'http://my.existing/#property'

$fedora->begin();

$resource = $fedora->getResourcesByProperty($conf->get('redmineIdProp'), 'https://redmine.acdh.oeaw.ac.at/issues/5488')[0];
$metadata = $resource->getMetadata();
foreach(array('value1', 'value2') as $i){
    $metadata->addLiteral($myExistingProperty, $i);
}
$resource->setMetadata($metadata);
$resource->updateMetadata();

$fedora->commit();

坏例子3。您将最终得到属性的最后一个添加值。

$myMultivalueProperty = 'http://my.existing/#property'

$fedora->begin();

$resource = $fedora->getResourcesByProperty($conf->get('redmineIdProp'), 'https://redmine.acdh.oeaw.ac.at/issues/5488')[0];
$metadata = $resource->getMetadata();
foreach(array('value1', 'value2') as $i){
    $metadata->delete($myMultivalueProperty);
    $metadata->addLiteral($myMultivalueProperty, $i);
}
$resource->setMetadata($metadata);
$resource->updateMetadata();

$fedora->commit();

更新资源二进制数据

更新资源二进制数据很简单。只需获取acdhOeaw\fedora\FedoraResource对象(见上文)并调用updateContent()方法。

$fedora->begin();

$resource = $fedora->getResourceById('https://id.acdh.oeaw.ac.at/myResource');
$resource->updateContent('pathToFile'); // with data in file
$resource->updateContent('new content of the resource'); // with data passed directly

$fedora->commit();

同步Redmine与Fedora

有一组用于同步各种Redmine对象(项目、用户和问题)与Fedora的类:acdhOeaw\schema\redmine\ProjectacdhOeaw\schema\redmine\UseracdhOeaw\schema\redmine\Issue

使用它们非常简单 - 静态fetchAll()方法创建代表特定类型Redmine对象的PHP对象,然后可以通过调用它们的updateRms()方法将它们保存/更新到Fedora中。

此外,Issue类的fetchAll()方法允许您指定Redmine REST API接受的任何过滤器。

例如,同步所有tracker_id等于5的Redmine问题可以这样完成

$fedora->begin();

$issues = acdhOeaw\redmine\Redmine::fetchAllIssues($fedora, true, ['tracker_id' => 5]);
foreach ($issues as $i) {
    $i->updateRms();
}

$fedora->commit();

在文件系统中索引文件

库提供了acdhOeaw\util\Indexer类,该类自动化了将二进制内容摄入/更新到Fedora的过程。

Indexer类基于acdhOeaw\fedora\FedoraResource对象创建,该对象将是摄入资源的父对象。这意味着您必须首先实例化此类。

Indexer类高度可配置 - 请参阅类文档以获取所有详细信息。

下面我们将索引给定目录及其直接子目录中的所有xml文件,将它们作为FedoraResouce的直接子项(这意味着不会为在文件系统中找到的子目录创建集合资源)。所有小于100 MB的文件将被摄入到存储库中,对于更大的文件,将创建纯元数据的Fedora资源。

$fedora->begin();

$resource = $fedora->getResourceById('https://redmine.acdh.oeaw.ac.at/issues/5488');
$ind = new acdhOeaw\util\Indexer($resource);
$ind->setFilter('|[.]xml$|i');
$ind->setPaths(array('directoryToIndex')); // read next chapter
$ind->setUploadSizeLimit(100000000);
$ind->setDepth(1);
$ind->setFlatStructure(true);
$ind->index();

$fedora->commit();

文件是如何与存储库资源匹配的

通过比较现有资源的ID与调整后的文件路径来将文件与存储库资源匹配。
文件路径通过以下方式调整

  • 将配置属性containerDir的值替换为配置属性containerToUriPrefix的值
  • 更改字符编码为UTF-8
  • 将所有\切换为/

务必确保您的配置属性值containerDircontainerToUriPrefix是正确的!(如果它们会导致生成您期望的ID)

如果它们不是,您在下一次导入时可能会遇到数据重复的风险。

示例 1

  • config.ini
    containerDir=./
    containerToUriPrefix=acdhContainer://
  • 文件路径:./myProject/myCollection/myFile.xml

该文件将与具有以下 id 的资源匹配:acdhContainer://myProject/myCollection/myFile.xml

示例 2

  • config.ini
    containerDir=C:\my\data\dir\
    containerToUriPrefix=https://id.acdh.oeaw.ac.at/
  • 文件路径:C:\my\data\dir\myProject\myCollection\myFile.xml

该文件将与具有以下 id 的资源匹配:https://id.acdh.oeaw.ac.at/myProject/myCollection/myFile.xml

匹配索引数据与其元数据

可以将一个 元数据查找对象 提供给 Indexer 对象。

一个 元数据查找对象 提供了文件路径和从该文件中提取的元数据。根据这些数据,它应该找到并返回给定文件的辅助元数据。

目前存在两种 元数据查找 实现

  • MetaLookupFile 类,它会在附加文件中搜索辅助元数据(通过文件名匹配),例如:
    // for the file path `/my/file/path.xml` search for metadata in files `/my/file/path.xml.ttl`, `/my/file/path/meta/path.xml.ttl` and `/some/dir/path.xml.ttl`
    // locations are searched in the given order, first metadata file found is used
    // such a file must contain only one resource being triples subject (if there are more, an exception is rised)
    $metaLookup = new acdhOeaw\util\metaLookup\MetaLookupFile(array('.', './meta', '/some/dir'), '.ttl');
    
    $ind = new Indexer($someResource);
    $ind->setMetaLookup($metaLookup);
    $ind->index();
  • MetaLookupGraph 类,它会在给定的 RDF 图中搜索辅助元数据(通过 id 匹配,如前一章所述),例如:
    $graph = new EasyRdf\Graph();
    $graph->parseFile('pathToMetadataFile.ttl');
    $metaLookup = new acdhOeaw\util\metaLookup\MetaLookupGraph($graph);
    
    $ind = new Indexer($someResource);
    $ind->setMetaLookup($metaLookup);
    $ind->index();

导入一组 RDF 数据

如果您有一组以 RDF 图的形式存在的数据,您可以使用 MetadataCollection 类轻松地导入它。

管理访问权限

每个 FedoraResource 对象都提供了一个相应的 WebAcl 对象,可用于访问权限管理,例如,授予 user 写入权限和对公众的读取权限

$fedora->begin();
$res = $fedora->getResourceById('https://my.id');
$aclObj = $res->getAcl();
$aclObj->grant(acdhOeaw\fedora\acl\WebAclRule::USER, 'user1', acdhOeaw\fedora\acl\WebAclRule::WRITE);
$aclObj->grant(acdhOeaw\fedora\acl\WebAclRule::USER, acdhOeaw\fedora\acl\WebAclRule::PUBLIC_USER, acdhOeaw\fedora\acl\WebAclRule::READ);
$fedora->commit();

权限也可以自动应用于子项(在 ACDH 仓库术语中),例如,直接子项和二阶子项

$fedora->begin();
$res = $fedora->getResourceById('https://my.id');
$aclObj = $res->getAcl();
$aclObj->grant(acdhOeaw\fedora\acl\WebAclRule::USER, 'user1', acdhOeaw\fedora\acl\WebAclRule::WRITE, 2);
$fedora->commit();

同样存在一个 revoke() 方法以及用于管理基于 RDF 类的访问规则的方法。

请参阅文档以获取详细信息。