Skip to content

Commit 8fdf59e

Browse files
authored
Merge pull request #52 from OPUS4/issue43
Import rules
2 parents 6a050c3 + c88f257 commit 8fdf59e

32 files changed

Lines changed: 2721 additions & 8 deletions

.github/workflows/php.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
jobs:
1010
build:
1111

12-
runs-on: ubuntu-22.04
12+
runs-on: ubuntu-24.04
1313

1414
strategy:
1515
matrix:
@@ -18,7 +18,7 @@ jobs:
1818
name: PHP ${{ matrix.php-versions }} Test
1919

2020
steps:
21-
- uses: actions/checkout@v3
21+
- uses: actions/checkout@v5
2222

2323
- name: Setup PHP ${{ matrix.php-versions }}
2424
uses: shivammathur/setup-php@v2

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"ext-dom": "*",
1414
"ext-fileinfo": "*",
1515
"ext-libxml": "*",
16+
"ext-mbstring": "*",
1617
"ext-zip": "*",
1718
"opus4-repo/opus4-common": "dev-master as 4.8.1",
1819
"opus4-repo/opus4-app-common": "dev-main",

src/ArrayImport.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@
3333

3434
use Opus\Common\Document;
3535

36+
/**
37+
* Imports documents from array.
38+
*
39+
* TODO What is the use case, besides an easy way to test import mechanisms.
40+
* TODO Interface?
41+
* TODO support multiple documents?
42+
*/
3643
class ArrayImport
3744
{
3845
/**
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/**
4+
* This file is part of OPUS. The software OPUS has been originally developed
5+
* at the University of Stuttgart with funding from the German Research Net,
6+
* the Federal Department of Higher Education and Research and the Ministry
7+
* of Science, Research and the Arts of the State of Baden-Wuerttemberg.
8+
*
9+
* OPUS 4 is a complete rewrite of the original OPUS software and was developed
10+
* by the Stuttgart University Library, the Library Service Center
11+
* Baden-Wuerttemberg, the Cooperative Library Network Berlin-Brandenburg,
12+
* the Saarland University and State Library, the Saxon State Library -
13+
* Dresden State and University Library, the Bielefeld University Library and
14+
* the University Library of Hamburg University of Technology with funding from
15+
* the German Research Foundation and the European Regional Development Fund.
16+
*
17+
* LICENCE
18+
* OPUS is free software; you can redistribute it and/or modify it under the
19+
* terms of the GNU General Public License as published by the Free Software
20+
* Foundation; either version 2 of the Licence, or any later version.
21+
* OPUS is distributed in the hope that it will be useful, but WITHOUT ANY
22+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
23+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
24+
* details. You should have received a copy of the GNU General Public License
25+
* along with OPUS; if not, write to the Free Software Foundation, Inc., 51
26+
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
*
28+
* @copyright Copyright (c) 2023, OPUS 4 development team
29+
* @license http://www.gnu.org/licenses/gpl.html General Public License
30+
*/
31+
32+
namespace Opus\Import;
33+
34+
use Opus\Common\DocumentInterface;
35+
36+
interface ImportRuleConditionInterface
37+
{
38+
/**
39+
* @param DocumentInterface $document
40+
* @return bool
41+
*/
42+
public function applies($document);
43+
}

src/ImportRuleInterface.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/**
4+
* This file is part of OPUS. The software OPUS has been originally developed
5+
* at the University of Stuttgart with funding from the German Research Net,
6+
* the Federal Department of Higher Education and Research and the Ministry
7+
* of Science, Research and the Arts of the State of Baden-Wuerttemberg.
8+
*
9+
* OPUS 4 is a complete rewrite of the original OPUS software and was developed
10+
* by the Stuttgart University Library, the Library Service Center
11+
* Baden-Wuerttemberg, the Cooperative Library Network Berlin-Brandenburg,
12+
* the Saarland University and State Library, the Saxon State Library -
13+
* Dresden State and University Library, the Bielefeld University Library and
14+
* the University Library of Hamburg University of Technology with funding from
15+
* the German Research Foundation and the European Regional Development Fund.
16+
*
17+
* LICENCE
18+
* OPUS is free software; you can redistribute it and/or modify it under the
19+
* terms of the GNU General Public License as published by the Free Software
20+
* Foundation; either version 2 of the Licence, or any later version.
21+
* OPUS is distributed in the hope that it will be useful, but WITHOUT ANY
22+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
23+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
24+
* details. You should have received a copy of the GNU General Public License
25+
* along with OPUS; if not, write to the Free Software Foundation, Inc., 51
26+
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
*
28+
* @copyright Copyright (c) 2023, OPUS 4 development team
29+
* @license http://www.gnu.org/licenses/gpl.html General Public License
30+
*/
31+
32+
namespace Opus\Import;
33+
34+
interface ImportRuleInterface
35+
{
36+
}

src/ImportRules.php

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<?php
2+
3+
/**
4+
* This file is part of OPUS. The software OPUS has been originally developed
5+
* at the University of Stuttgart with funding from the German Research Net,
6+
* the Federal Department of Higher Education and Research and the Ministry
7+
* of Science, Research and the Arts of the State of Baden-Wuerttemberg.
8+
*
9+
* OPUS 4 is a complete rewrite of the original OPUS software and was developed
10+
* by the Stuttgart University Library, the Library Service Center
11+
* Baden-Wuerttemberg, the Cooperative Library Network Berlin-Brandenburg,
12+
* the Saarland University and State Library, the Saxon State Library -
13+
* Dresden State and University Library, the Bielefeld University Library and
14+
* the University Library of Hamburg University of Technology with funding from
15+
* the German Research Foundation and the European Regional Development Fund.
16+
*
17+
* LICENCE
18+
* OPUS is free software; you can redistribute it and/or modify it under the
19+
* terms of the GNU General Public License as published by the Free Software
20+
* Foundation; either version 2 of the Licence, or any later version.
21+
* OPUS is distributed in the hope that it will be useful, but WITHOUT ANY
22+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
23+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
24+
* details. You should have received a copy of the GNU General Public License
25+
* along with OPUS; if not, write to the Free Software Foundation, Inc., 51
26+
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
*
28+
* @copyright Copyright (c) 2023, OPUS 4 development team
29+
* @license http://www.gnu.org/licenses/gpl.html General Public License
30+
*/
31+
32+
namespace Opus\Import;
33+
34+
use Opus\Common\ConfigTrait;
35+
use Opus\Common\DocumentInterface;
36+
use Zend_Config_Ini;
37+
38+
use function class_exists;
39+
use function filter_var;
40+
use function is_array;
41+
use function is_readable;
42+
43+
use const FILTER_VALIDATE_BOOLEAN;
44+
45+
class ImportRules
46+
{
47+
use ConfigTrait;
48+
49+
public const IMPORT_RULE_CLASS_PREFIX = 'Opus\\Import\\Rules\\';
50+
51+
/** @var ImportRuleInterface[] */
52+
private $rules = [];
53+
54+
/**
55+
* Loads rules from configuration.
56+
*/
57+
public function init()
58+
{
59+
$config = $this->getConfig();
60+
61+
if (
62+
! isset($config->sword->enableImportRules) ||
63+
! filter_var($config->sword->enableImportRules, FILTER_VALIDATE_BOOLEAN)
64+
) {
65+
// TODO does this belong here? There should not be anything SWORD specific here!
66+
return; // don't load any rules
67+
}
68+
69+
$rulesConfig = null;
70+
71+
if (isset($config->import->rulesConfigFile)) {
72+
$rulesConfigFile = $config->import->rulesConfigFile;
73+
if (is_readable($rulesConfigFile)) {
74+
$rulesConfig = new Zend_Config_Ini($rulesConfigFile);
75+
$rulesConfig = $rulesConfig->toArray();
76+
}
77+
}
78+
79+
// Get rules from main configuration as fallback
80+
if ($rulesConfig === null && isset($config->import->rules)) {
81+
$rulesConfig = $config->import->rules->toArray();
82+
}
83+
84+
if (is_array($rulesConfig)) {
85+
foreach ($rulesConfig as $name => $options) {
86+
$type = $options['type'];
87+
88+
$rule = $this->createRule($type, $options);
89+
90+
if ($rule !== null) {
91+
$this->rules[] = $rule;
92+
}
93+
}
94+
}
95+
}
96+
97+
/**
98+
* @return ImportRuleInterface[]
99+
*/
100+
public function getRules()
101+
{
102+
return $this->rules;
103+
}
104+
105+
/**
106+
* @param string $type
107+
* @param array $options
108+
* @return ImportRuleInterface|null
109+
*/
110+
public function createRule($type, $options)
111+
{
112+
if (class_exists($type)) {
113+
$ruleClass = $type;
114+
} else {
115+
$ruleClass = self::IMPORT_RULE_CLASS_PREFIX . $type;
116+
if (! class_exists($ruleClass)) {
117+
// TODO throw exception
118+
return null;
119+
}
120+
}
121+
122+
$rule = new $ruleClass();
123+
$rule->setOptions($options);
124+
125+
return $rule;
126+
}
127+
128+
/**
129+
* @param DocumentInterface $document
130+
*/
131+
public function apply($document)
132+
{
133+
foreach ($this->getRules() as $rule) {
134+
$rule->apply($document);
135+
}
136+
}
137+
}

src/Importer.php

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ class Importer
127127
/** @var XmlDocument */
128128
private $xmlDocument;
129129

130+
/** @var ImportRules */
131+
private $importRules;
132+
130133
/** @var bool */
131134
private $updateExistingDocuments = true;
132135

@@ -319,6 +322,9 @@ public function run()
319322
continue;
320323
}
321324

325+
$importRules = $this->getImportRules();
326+
$importRules->apply($doc);
327+
322328
try {
323329
// TODO post "import" processing before storing!
324330
$newDocId = $doc->store();
@@ -713,9 +719,11 @@ protected function handleKeywords($node, $doc)
713719
{
714720
foreach ($node->childNodes as $childNode) {
715721
if ($childNode instanceof DOMElement) {
716-
$s = Subject::new();
717-
$s->setLanguage(trim($childNode->getAttribute('language')));
718-
$s->setType($childNode->getAttribute('type'));
722+
$s = Subject::new();
723+
$language = $childNode->getAttribute('language');
724+
$s->setLanguage($language ?: 'deu');
725+
$type = $childNode->getAttribute('type');
726+
$s->setType($type ?: 'uncontrolled');
719727
$s->setValue(trim($childNode->textContent));
720728
$doc->addSubject($s);
721729
}
@@ -1128,6 +1136,19 @@ public function getDocument(): DocumentInterface
11281136
return $this->document;
11291137
}
11301138

1139+
/**
1140+
* @return ImportRules
1141+
*/
1142+
public function getImportRules()
1143+
{
1144+
if ($this->importRules === null) {
1145+
$this->importRules = new ImportRules();
1146+
$this->importRules->init();
1147+
}
1148+
1149+
return $this->importRules;
1150+
}
1151+
11311152
protected function setSingleDocImport(bool $singleDoc): self
11321153
{
11331154
$this->singleDocImport = $singleDoc;

src/Rules/AbstractImportRule.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
/**
4+
* This file is part of OPUS. The software OPUS has been originally developed
5+
* at the University of Stuttgart with funding from the German Research Net,
6+
* the Federal Department of Higher Education and Research and the Ministry
7+
* of Science, Research and the Arts of the State of Baden-Wuerttemberg.
8+
*
9+
* OPUS 4 is a complete rewrite of the original OPUS software and was developed
10+
* by the Stuttgart University Library, the Library Service Center
11+
* Baden-Wuerttemberg, the Cooperative Library Network Berlin-Brandenburg,
12+
* the Saarland University and State Library, the Saxon State Library -
13+
* Dresden State and University Library, the Bielefeld University Library and
14+
* the University Library of Hamburg University of Technology with funding from
15+
* the German Research Foundation and the European Regional Development Fund.
16+
*
17+
* LICENCE
18+
* OPUS is free software; you can redistribute it and/or modify it under the
19+
* terms of the GNU General Public License as published by the Free Software
20+
* Foundation; either version 2 of the Licence, or any later version.
21+
* OPUS is distributed in the hope that it will be useful, but WITHOUT ANY
22+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
23+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
24+
* details. You should have received a copy of the GNU General Public License
25+
* along with OPUS; if not, write to the Free Software Foundation, Inc., 51
26+
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
*
28+
* @copyright Copyright (c) 2023, OPUS 4 development team
29+
* @license http://www.gnu.org/licenses/gpl.html General Public License
30+
*/
31+
32+
namespace Opus\Import\Rules;
33+
34+
use Opus\Common\DocumentInterface;
35+
use Opus\Import\ImportRuleConditionInterface;
36+
use Opus\Import\ImportRuleInterface;
37+
use Opus\Import\Rules\Conditions\AccountCondition;
38+
use Opus\Import\Rules\Conditions\KeywordCondition;
39+
40+
/**
41+
* TODO add base class for common code
42+
*/
43+
abstract class AbstractImportRule implements ImportRuleInterface
44+
{
45+
/** @var ImportRuleConditionInterface */
46+
private $condition;
47+
48+
/**
49+
* @param array $options
50+
*/
51+
public function setOptions($options)
52+
{
53+
if (isset($options['condition'])) {
54+
$condition = $options['condition'];
55+
// TODO support multiple conditions
56+
if (isset($condition['account'])) {
57+
$this->condition = new AccountCondition($condition);
58+
}
59+
if (isset($condition['keyword'])) {
60+
$this->condition = new KeywordCondition($condition);
61+
}
62+
}
63+
}
64+
65+
/**
66+
* @return ImportRuleConditionInterface
67+
*/
68+
public function getCondition()
69+
{
70+
return $this->condition;
71+
}
72+
73+
/**
74+
* @param DocumentInterface $document
75+
*/
76+
public function apply($document)
77+
{
78+
// TODO condition check in base class?
79+
}
80+
}

0 commit comments

Comments
 (0)