Skip to content

Commit 3851c56

Browse files
Merge branch 'fixReport340-907' into 'main'
Corrige problema com relatório - 3.4.0 See merge request softwares-pkp/plugins_ojs/dataverse!224
2 parents 1cca0b8 + 04bba17 commit 3851c56

5 files changed

Lines changed: 107 additions & 50 deletions

File tree

dataverseAPI/search/DataverseSearchBuilder.php

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
class DataverseSearchBuilder
1010
{
11+
private const URL_MAX_LENGTH = 4096;
12+
1113
private $configuration;
1214
private $httpClient;
1315
private $queries = [];
@@ -43,43 +45,53 @@ public function addFilterQuery(string $field, string $value): DataverseSearchBui
4345
return $this;
4446
}
4547

46-
public function getParams(): string
48+
private function escapeColon(string $value): string
4749
{
48-
if (empty($this->queries)) {
49-
$this->addQuery('*');
50-
}
50+
return str_replace(':', '\:', $value);
51+
}
5152

52-
$search = 'q=' . implode('+', $this->queries);
53+
public function getSearchUrls(): array
54+
{
55+
$baseUrl = $this->getDataverseSearchEndpoint() . '?';
56+
$queries = empty($this->queries) ? ['*'] : $this->queries;
57+
$baseUrl .= 'q=' . implode('+', $queries);
5358

5459
if (!empty($this->types)) {
55-
$search .= '&type=' . implode('&type=', $this->types);
60+
$baseUrl .= '&type=' . implode('&type=', $this->types);
5661
}
5762

58-
if (!empty($this->filterQueries)) {
59-
$search .= '&fq=' . implode('+', array_map(function (array $filterQuery) {
60-
$field = key($filterQuery);
61-
$value = $filterQuery[$field];
62-
return $field . ':' . $this->escapeColon($value);
63-
}, $this->filterQueries));
63+
if (empty($this->filterQueries)) {
64+
return [$baseUrl];
6465
}
6566

66-
return $search;
67-
}
68-
69-
private function escapeColon(string $value): string
70-
{
71-
return str_replace(':', '\:', $value);
72-
}
67+
$filterParts = array_map(function (array $filterQuery) {
68+
$field = key($filterQuery);
69+
$value = $filterQuery[$field];
70+
return $field . ':' . $this->escapeColon($value);
71+
}, $this->filterQueries);
72+
73+
$urls = [];
74+
$filterPartsCount = count($filterParts);
75+
for ($i = 0; $i < $filterPartsCount; $i = $j) {
76+
$currentUrl = $baseUrl . '&fq=' . $filterParts[$i];
77+
78+
for ($j = $i + 1; $j < $filterPartsCount; $j++) {
79+
$nextFilterPart = '+' . $filterParts[$j];
80+
if ((strlen($currentUrl) + strlen($nextFilterPart)) > self::URL_MAX_LENGTH) {
81+
break;
82+
}
83+
$currentUrl .= $nextFilterPart;
84+
}
85+
$urls[] = $currentUrl;
86+
}
7387

74-
public function getSearchUrl(): string
75-
{
76-
return $this->getDataverseSearchEndpoint() . '?' . $this->getParams();
88+
return $urls;
7789
}
7890

79-
public function search(): DataverseResponse
91+
private function executeRequest(string $url): DataverseResponse
8092
{
8193
try {
82-
$response = $this->httpClient->request('GET', $this->getSearchUrl(), [
94+
$response = $this->httpClient->request('GET', $url, [
8395
'headers' => [
8496
'X-Dataverse-key' => $this->configuration->getAPIToken()
8597
]
@@ -106,4 +118,25 @@ public function search(): DataverseResponse
106118
$response->getBody()
107119
);
108120
}
121+
122+
public function search(): array
123+
{
124+
$responses = [];
125+
foreach ($this->getSearchUrls() as $url) {
126+
$responses[] = $this->executeRequest($url);
127+
}
128+
return $responses;
129+
}
130+
131+
public function count(): int
132+
{
133+
$total = 0;
134+
foreach ($this->search() as $response) {
135+
$body = json_decode($response->getBody(), true);
136+
if (isset($body['data']['total_count'])) {
137+
$total += $body['data']['total_count'];
138+
}
139+
}
140+
return $total;
141+
}
109142
}

report/services/DataverseReportService.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,7 @@ public function countDatasetFiles(int $contextId): int
113113
$searchBuilder->addFilterQuery('parentIdentifier', $submission->persistent_id);
114114
}
115115

116-
$response = $searchBuilder->search();
117-
$data = json_decode($response->getBody(), true);
118-
return $data['data']['total_count'];
116+
return $searchBuilder->count();
119117
}
120118

121119
public function getDataverseSearchBuilder(int $contextId): DataverseSearchBuilder

tests/dataverseAPI/search/DataverseSearchBuilderTest.php

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,36 @@
55

66
class DataverseSearchBuilderTest extends PHPUnit\Framework\TestCase
77
{
8+
private const DATAVERSE_URL = 'https://test.dataverse.org/dataverse/testDataverse';
9+
private const SEARCH_URL = 'https://test.dataverse.org/api/search?';
10+
811
private function getDataverseSearchBuilder(): DataverseSearchBuilder
912
{
1013
$configuration = new DataverseConfiguration();
1114
$httpClient = new \GuzzleHttp\Client();
1215

13-
$configuration->setDataverseUrl('https://test.dataverse.org/dataverse/testDataverse');
16+
$configuration->setDataverseUrl(self::DATAVERSE_URL);
1417

1518
return new DataverseSearchBuilder($configuration, $httpClient);
1619
}
1720

1821
public function testEmptyQuery(): void
1922
{
2023
$searchBuilder = $this->getDataverseSearchBuilder();
21-
$this->assertEquals('q=*', $searchBuilder->getParams());
24+
$this->assertEquals(
25+
[self::SEARCH_URL . 'q=*'],
26+
$searchBuilder->getSearchUrls()
27+
);
2228
}
2329

2430
public function testSingleQuery(): void
2531
{
2632
$searchBuilder = $this->getDataverseSearchBuilder();
2733
$searchBuilder->addQuery('test');
28-
$this->assertEquals('q=test', $searchBuilder->getParams());
34+
$this->assertEquals(
35+
[self::SEARCH_URL . 'q=test'],
36+
$searchBuilder->getSearchUrls()
37+
);
2938
}
3039

3140
public function testMultipleQueries(): void
@@ -34,14 +43,20 @@ public function testMultipleQueries(): void
3443
->addQuery('title:test')
3544
->addQuery('language:English');
3645

37-
$this->assertEquals('q=title:test+language:English', $searchBuilder->getParams());
46+
$this->assertEquals(
47+
[self::SEARCH_URL . 'q=title:test+language:English'],
48+
$searchBuilder->getSearchUrls()
49+
);
3850
}
3951

4052
public function testSingleType(): void
4153
{
4254
$searchBuilder = $this->getDataverseSearchBuilder();
4355
$searchBuilder->addType('dataset');
44-
$this->assertEquals('q=*&type=dataset', $searchBuilder->getParams());
56+
$this->assertEquals(
57+
[self::SEARCH_URL . 'q=*&type=dataset'],
58+
$searchBuilder->getSearchUrls()
59+
);
4560
}
4661

4762
public function testMultipleTypes(): void
@@ -50,14 +65,20 @@ public function testMultipleTypes(): void
5065
->addType('dataset')
5166
->addType('file');
5267

53-
$this->assertEquals('q=*&type=dataset&type=file', $searchBuilder->getParams());
68+
$this->assertEquals(
69+
[self::SEARCH_URL . 'q=*&type=dataset&type=file'],
70+
$searchBuilder->getSearchUrls()
71+
);
5472
}
5573

5674
public function testSingleFilterQuery(): void
5775
{
5876
$searchBuilder = $this->getDataverseSearchBuilder();
5977
$searchBuilder->addFilterQuery('publicationDate', '2016');
60-
$this->assertEquals('q=*&fq=publicationDate:2016', $searchBuilder->getParams());
78+
$this->assertEquals(
79+
[self::SEARCH_URL . 'q=*&fq=publicationDate:2016'],
80+
$searchBuilder->getSearchUrls()
81+
);
6182
}
6283

6384
public function testMultipleFilterQueries(): void
@@ -66,7 +87,10 @@ public function testMultipleFilterQueries(): void
6687
->addFilterQuery('publicationDate', '2016')
6788
->addFilterQuery('publicationStatus', 'Published');
6889

69-
$this->assertEquals('q=*&fq=publicationDate:2016+publicationStatus:Published', $searchBuilder->getParams());
90+
$this->assertEquals(
91+
[self::SEARCH_URL . 'q=*&fq=publicationDate:2016+publicationStatus:Published'],
92+
$searchBuilder->getSearchUrls()
93+
);
7094
}
7195

7296
public function testFullParamsSearch(): void
@@ -77,22 +101,24 @@ public function testFullParamsSearch(): void
77101
->addFilterQuery('publicationStatus', 'Published');
78102

79103
$this->assertEquals(
80-
'q=foo&type=dataset&fq=publicationStatus:Published',
81-
$searchBuilder->getParams()
104+
[self::SEARCH_URL . 'q=foo&type=dataset&fq=publicationStatus:Published'],
105+
$searchBuilder->getSearchUrls()
82106
);
83107
}
84108

85-
public function testBuildDataverseSearchUrl(): void
109+
public function testLargeNumberOfFiltersGenerateMultipleUrls(): void
86110
{
87-
$searchBuilder = $this->getDataverseSearchBuilder()
88-
->addQuery('foo')
89-
->addType('dataset')
90-
->addType('file')
91-
->addFilterQuery('publicationStatus', 'Published');
111+
$largeNumberOfFilters = 1000;
112+
$searchBuilder = $this->getDataverseSearchBuilder();
113+
for ($i = 0; $i < $largeNumberOfFilters; $i++) {
114+
$searchBuilder->addFilterQuery('publicationStatus', 'Published');
115+
}
92116

93-
$this->assertEquals(
94-
'https://test.dataverse.org/api/search?q=foo&type=dataset&type=file&fq=publicationStatus:Published',
95-
$searchBuilder->getSearchUrl()
96-
);
117+
$searchUrls = $searchBuilder->getSearchUrls();
118+
119+
$this->assertGreaterThan(1, count($searchUrls));
120+
foreach ($searchUrls as $searchUrl) {
121+
$this->assertStringContainsString(self::SEARCH_URL, $searchUrl);
122+
}
97123
}
98124
}

upgrade.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!DOCTYPE install SYSTEM "../../../lib/pkp/dtd/install.dtd">
33

4-
<install version="3.4.2.0">
4+
<install version="3.4.2.1">
55
<migration class="APP\plugins\generic\dataverse\classes\migrations\APITokenEncryptionMigration" />
66
</install>

version.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
<version>
1414
<application>dataverse</application>
1515
<type>plugins.generic</type>
16-
<release>3.4.2.0</release>
17-
<date>2026-05-08</date>
16+
<release>3.4.2.1</release>
17+
<date>2026-05-12</date>
1818
<lazy-load>1</lazy-load>
1919
<class>DataversePlugin</class>
2020
</version>

0 commit comments

Comments
 (0)