Skip to content

Commit 6afa031

Browse files
committed
Merge branch 'update_thoth_schema-3_5_0-i1176' into 'main'
Update thoth schema integration (3.5.0) See merge request softwares-pkp/plugins_ojs/thoth-omp-plugin!103
2 parents c61ae96 + 7ab7427 commit 6afa031

File tree

57 files changed

+2057
-176
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2057
-176
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,4 @@ This plugin is licensed under the GNU General Public License v3.0 - [See the Lic
164164

165165
Copyright (c) 2024-2026 Lepidus Tecnologia
166166

167-
Copyright (c) 2024-2026 Thoth
167+
Copyright (c) 2024-2026 Thoth Open Metadata

ThothSettingsForm.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
use APP\template\TemplateManager;
2222
use GuzzleHttp\Exception\GuzzleException;
23+
use Illuminate\Contracts\Encryption\DecryptException;
2324
use Illuminate\Support\Facades\Crypt;
2425
use PKP\form\Form;
2526
use PKP\form\validation\FormValidatorCSRF;
@@ -94,9 +95,16 @@ public function initData(): void
9495
{
9596
foreach (self::SETTINGS as $setting) {
9697
$value = $this->plugin->getSetting($this->contextId, $setting);
98+
if ($setting === 'token' && $value) {
99+
try {
100+
$value = Crypt::decrypt($value);
101+
} catch (DecryptException $exception) {
102+
$value = '';
103+
}
104+
}
97105
$this->setData(
98106
$setting,
99-
$setting === 'token' && $value ? Crypt::decrypt($value) : $value
107+
$value
100108
);
101109
}
102110
}

classes/api/ThothEndpoint.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public function register(IlluminateRequest $illuminateRequest): JsonResponse
123123
$this->handleNotification($request, $submission, true, $disableNotification);
124124
} catch (QueryException $e) {
125125
$thothBookService->deleteRegisteredEntry();
126-
$this->handleNotification($request, $submission, false, $disableNotification, $e->getMessage());
126+
$this->handleNotification($request, $submission, false, $disableNotification, $e);
127127
$failure['errors'][] = __('plugins.generic.thoth.register.error.log', ['reason' => $e->getMessage()]);
128128
return response()->json($failure, Response::HTTP_BAD_REQUEST);
129129
}

classes/components/forms/config/PublishFormConfig.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use APP\facades\Repo;
2020
use APP\plugins\generic\thoth\classes\facades\ThothRepository;
2121
use APP\plugins\generic\thoth\classes\facades\ThothService;
22+
use APP\plugins\generic\thoth\classes\notification\ThothNotification;
2223
use APP\submission\Submission;
2324
use ThothApi\GraphQL\Models\Work as ThothWork;
2425

classes/container/providers/ThothRepositoryProvider.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020

2121
use APP\core\Application;
2222
use APP\plugins\generic\thoth\classes\repositories\ThothAccountRepository;
23+
use APP\plugins\generic\thoth\classes\repositories\ThothAbstractRepository;
2324
use APP\plugins\generic\thoth\classes\repositories\ThothAffiliationRepository;
25+
use APP\plugins\generic\thoth\classes\repositories\ThothBiographyRepository;
2426
use APP\plugins\generic\thoth\classes\repositories\ThothBookRepository;
2527
use APP\plugins\generic\thoth\classes\repositories\ThothChapterRepository;
2628
use APP\plugins\generic\thoth\classes\repositories\ThothContributionRepository;
@@ -32,8 +34,10 @@
3234
use APP\plugins\generic\thoth\classes\repositories\ThothPublicationRepository;
3335
use APP\plugins\generic\thoth\classes\repositories\ThothReferenceRepository;
3436
use APP\plugins\generic\thoth\classes\repositories\ThothSubjectRepository;
37+
use APP\plugins\generic\thoth\classes\repositories\ThothTitleRepository;
3538
use APP\plugins\generic\thoth\classes\repositories\ThothWorkRelationRepository;
3639
use APP\plugins\generic\thoth\classes\repositories\ThothWorkRepository;
40+
use Illuminate\Contracts\Encryption\DecryptException;
3741
use Illuminate\Support\Facades\Crypt;
3842
use PKP\db\DAORegistry;
3943
use ThothApi\GraphQL\Client;
@@ -49,11 +53,20 @@ public function register($container)
4953
$customThothApi = $pluginSettingsDao->getSetting($contextId, 'ThothPlugin', 'customThothApi');
5054
$customThothApiUrl = $pluginSettingsDao->getSetting($contextId, 'ThothPlugin', 'customThothApiUrl');
5155
$token = $pluginSettingsDao->getSetting($contextId, 'ThothPlugin', 'token') ?? '';
56+
$decryptedToken = '';
57+
58+
if ($token) {
59+
try {
60+
$decryptedToken = Crypt::decrypt($token);
61+
} catch (DecryptException $exception) {
62+
$decryptedToken = '';
63+
}
64+
}
5265

5366
return [
5467
'customThothApi' => $customThothApi,
5568
'customThothApiUrl' => $customThothApiUrl,
56-
'token' => $token ? Crypt::decrypt($token) : ''
69+
'token' => $decryptedToken
5770
];
5871
});
5972

@@ -73,6 +86,10 @@ public function register($container)
7386
return new ThothAccountRepository($container->get('client'));
7487
});
7588

89+
$container->set('abstractRepository', function ($container) {
90+
return new ThothAbstractRepository($container->get('client'));
91+
});
92+
7693
$container->set('affiliationRepository', function ($container) {
7794
return new ThothAffiliationRepository($container->get('client'));
7895
});
@@ -81,6 +98,10 @@ public function register($container)
8198
return new ThothBookRepository($container->get('client'));
8299
});
83100

101+
$container->set('biographyRepository', function ($container) {
102+
return new ThothBiographyRepository($container->get('client'));
103+
});
104+
84105
$container->set('chapterRepository', function ($container) {
85106
return new ThothChapterRepository($container->get('client'));
86107
});
@@ -121,6 +142,10 @@ public function register($container)
121142
return new ThothSubjectRepository($container->get('client'));
122143
});
123144

145+
$container->set('titleRepository', function ($container) {
146+
return new ThothTitleRepository($container->get('client'));
147+
});
148+
124149
$container->set('workRelationRepository', function ($container) {
125150
return new ThothWorkRelationRepository($container->get('client'));
126151
});

classes/container/providers/ThothServiceProvider.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,16 @@
1919

2020
use APP\plugins\generic\thoth\classes\factories\ThothBookFactory;
2121
use APP\plugins\generic\thoth\classes\factories\ThothChapterFactory;
22+
use APP\plugins\generic\thoth\classes\factories\ThothAbstractFactory;
23+
use APP\plugins\generic\thoth\classes\factories\ThothBiographyFactory;
2224
use APP\plugins\generic\thoth\classes\factories\ThothContributionFactory;
2325
use APP\plugins\generic\thoth\classes\factories\ThothContributorFactory;
2426
use APP\plugins\generic\thoth\classes\factories\ThothLocationFactory;
2527
use APP\plugins\generic\thoth\classes\factories\ThothPublicationFactory;
28+
use APP\plugins\generic\thoth\classes\factories\ThothTitleFactory;
2629
use APP\plugins\generic\thoth\classes\services\ThothAffiliationService;
30+
use APP\plugins\generic\thoth\classes\services\ThothAbstractService;
31+
use APP\plugins\generic\thoth\classes\services\ThothBiographyService;
2732
use APP\plugins\generic\thoth\classes\services\ThothBookService;
2833
use APP\plugins\generic\thoth\classes\services\ThothChapterService;
2934
use APP\plugins\generic\thoth\classes\services\ThothContributionService;
@@ -33,6 +38,7 @@
3338
use APP\plugins\generic\thoth\classes\services\ThothPublicationService;
3439
use APP\plugins\generic\thoth\classes\services\ThothReferenceService;
3540
use APP\plugins\generic\thoth\classes\services\ThothSubjectService;
41+
use APP\plugins\generic\thoth\classes\services\ThothTitleService;
3642
use APP\plugins\generic\thoth\classes\services\ThothWorkRelationService;
3743

3844
class ThothServiceProvider implements ContainerProvider
@@ -43,6 +49,20 @@ public function register($container)
4349
return new ThothAffiliationService($container->get('affiliationRepository'));
4450
});
4551

52+
$container->set('abstractService', function ($container) {
53+
return new ThothAbstractService(
54+
new ThothAbstractFactory(),
55+
$container->get('abstractRepository')
56+
);
57+
});
58+
59+
$container->set('biographyService', function ($container) {
60+
return new ThothBiographyService(
61+
new ThothBiographyFactory(),
62+
$container->get('biographyRepository')
63+
);
64+
});
65+
4666
$container->set('bookService', function ($container) {
4767
return new ThothBookService(
4868
new ThothBookFactory(),
@@ -97,6 +117,13 @@ public function register($container)
97117
return new ThothSubjectService($container->get('subjectRepository'));
98118
});
99119

120+
$container->set('titleService', function ($container) {
121+
return new ThothTitleService(
122+
new ThothTitleFactory(),
123+
$container->get('titleRepository')
124+
);
125+
});
126+
100127
$container->set('workRelationService', function ($container) {
101128
return new ThothWorkRelationService($container->get('workRelationRepository'));
102129
});

classes/facades/ThothRepository.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ public static function account()
2525
return ThothContainer::getInstance()->get('accountRepository');
2626
}
2727

28+
public static function abstract()
29+
{
30+
return ThothContainer::getInstance()->get('abstractRepository');
31+
}
32+
33+
public static function biography()
34+
{
35+
return ThothContainer::getInstance()->get('biographyRepository');
36+
}
37+
2838
public static function affiliation()
2939
{
3040
return ThothContainer::getInstance()->get('affiliationRepository');
@@ -75,6 +85,11 @@ public static function subject()
7585
return ThothContainer::getInstance()->get('subjectRepository');
7686
}
7787

88+
public static function title()
89+
{
90+
return ThothContainer::getInstance()->get('titleRepository');
91+
}
92+
7893
public static function workRelation()
7994
{
8095
return ThothContainer::getInstance()->get('workRelationRepository');

classes/facades/ThothService.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,21 @@
2020

2121
class ThothService
2222
{
23+
public static function abstract()
24+
{
25+
return ThothContainer::getInstance()->get('abstractService');
26+
}
27+
2328
public static function affiliation()
2429
{
2530
return ThothContainer::getInstance()->get('affiliationService');
2631
}
2732

33+
public static function biography()
34+
{
35+
return ThothContainer::getInstance()->get('biographyService');
36+
}
37+
2838
public static function book()
2939
{
3040
return ThothContainer::getInstance()->get('bookService');
@@ -75,6 +85,11 @@ public static function subject()
7585
return ThothContainer::getInstance()->get('subjectService');
7686
}
7787

88+
public static function title()
89+
{
90+
return ThothContainer::getInstance()->get('titleService');
91+
}
92+
7893
public static function workRelation()
7994
{
8095
return ThothContainer::getInstance()->get('workRelationService');
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?php
2+
3+
/**
4+
* @file plugins/generic/thoth/classes/factories/ThothAbstractFactory.php
5+
*
6+
* Copyright (c) 2024-2026 Lepidus Tecnologia
7+
* Copyright (c) 2024-2026 Thoth
8+
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
9+
*
10+
* @class ThothAbstractFactory
11+
*
12+
* @ingroup plugins_generic_thoth
13+
*
14+
* @brief A factory to create Thoth abstracts
15+
*/
16+
17+
namespace APP\plugins\generic\thoth\classes\factories;
18+
19+
use APP\plugins\generic\thoth\classes\i18n\ThothLocaleCode;
20+
use ThothApi\GraphQL\Models\AbstractText as ThothAbstract;
21+
22+
class ThothAbstractFactory
23+
{
24+
public function createFromPublication($publication, string $workId, ?string $preferredLocale = null): array
25+
{
26+
return $this->create($publication, $workId, $preferredLocale);
27+
}
28+
29+
public function createFromChapter($chapter, string $workId, ?string $preferredLocale = null): array
30+
{
31+
return $this->create($chapter, $workId, $preferredLocale);
32+
}
33+
34+
private function create($entity, string $workId, ?string $preferredLocale = null): array
35+
{
36+
$canonicalLocale = $this->getCanonicalLocale($entity, $preferredLocale);
37+
$abstracts = $this->getLocalizedValues($entity, 'abstract', $canonicalLocale);
38+
$thothAbstracts = [];
39+
40+
foreach ($abstracts as $locale => $abstract) {
41+
$localeCode = $this->getLocaleCode($locale);
42+
if ($localeCode === null) {
43+
$this->logUnsupportedLocale('abstract', $locale);
44+
continue;
45+
}
46+
47+
$thothAbstracts[$this->getLocaleKey($localeCode)] = new ThothAbstract([
48+
'workId' => $workId,
49+
'localeCode' => $localeCode,
50+
'content' => $this->wrapInParagraph($abstract),
51+
'canonical' => $locale === $canonicalLocale,
52+
'abstractType' => 'LONG',
53+
]);
54+
}
55+
56+
return $thothAbstracts;
57+
}
58+
59+
public function getCanonicalLocale($entity, ?string $preferredLocale = null): ?string
60+
{
61+
$locales = $this->getSupportedLocales($this->getLocalizedValues($entity, 'abstract', $preferredLocale));
62+
63+
if ($preferredLocale && in_array($preferredLocale, $locales, true)) {
64+
return $preferredLocale;
65+
}
66+
67+
return $locales[0] ?? $preferredLocale;
68+
}
69+
70+
public function getLocaleKey(?string $localeCode): string
71+
{
72+
return $localeCode ?? '';
73+
}
74+
75+
private function getLocalizedValues($entity, string $key, ?string $fallbackLocale = null): array
76+
{
77+
$values = $entity->getData($key);
78+
if (is_array($values)) {
79+
return array_filter($values, fn ($value) => $value !== null && $value !== '');
80+
}
81+
82+
if ($values !== null && $values !== '' && $fallbackLocale) {
83+
return [$fallbackLocale => $values];
84+
}
85+
86+
return [];
87+
}
88+
89+
private function getLocaleCode(?string $locale): ?string
90+
{
91+
return ThothLocaleCode::fromPkpLocale($locale);
92+
}
93+
94+
private function getSupportedLocales(array $localizedValues): array
95+
{
96+
return array_values(array_filter(
97+
array_keys($localizedValues),
98+
fn (string $locale): bool => $this->getLocaleCode($locale) !== null
99+
));
100+
}
101+
102+
private function logUnsupportedLocale(string $entityType, ?string $locale): void
103+
{
104+
$normalizedLocaleCode = $locale ? strtoupper(str_replace(['-', '@'], '_', $locale)) : 'NULL';
105+
error_log(sprintf(
106+
'[thoth] Skipping unsupported locale for %s: sourceLocale=%s normalizedLocaleCode=%s',
107+
$entityType,
108+
$locale ?? 'NULL',
109+
$normalizedLocaleCode
110+
));
111+
}
112+
113+
private function wrapInParagraph(string $content): string
114+
{
115+
$content = trim($content);
116+
if (preg_match('/^<p\b[^>]*>.*<\/p>$/is', $content) === 1) {
117+
return $content;
118+
}
119+
120+
return sprintf('<p>%s</p>', $content);
121+
}
122+
}

0 commit comments

Comments
 (0)