Skip to content

Commit 6b43f45

Browse files
Merge branch 'fixReport330-907' into 'stable-3_3_0'
Corrige problema com relatório - 3.3.0 See merge request softwares-pkp/plugins_ojs/dataverse!225
2 parents 7b57119 + 83834ab commit 6b43f45

5 files changed

Lines changed: 108 additions & 50 deletions

File tree

dataverseAPI/search/DataverseSearchBuilder.inc.php

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

66
class DataverseSearchBuilder
77
{
8+
private const URL_MAX_LENGTH = 4096;
9+
810
private $configuration;
911

1012
private $httpClient;
@@ -44,43 +46,53 @@ public function addFilterQuery(string $field, string $value): DataverseSearchBui
4446
return $this;
4547
}
4648

47-
public function getParams(): string
49+
private function escapeColon(string $value): string
4850
{
49-
if (empty($this->queries)) {
50-
$this->addQuery('*');
51-
}
51+
return str_replace(':', '\:', $value);
52+
}
5253

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

5560
if (!empty($this->types)) {
56-
$search .= '&type=' . implode('&type=', $this->types);
61+
$baseUrl .= '&type=' . implode('&type=', $this->types);
5762
}
5863

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

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

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

80-
public function search(): DataverseResponse
92+
private function executeRequest(string $url): DataverseResponse
8193
{
8294
try {
83-
$response = $this->httpClient->request('GET', $this->getSearchUrl(), [
95+
$response = $this->httpClient->request('GET', $url, [
8496
'headers' => [
8597
'X-Dataverse-key' => $this->configuration->getAPIToken()
8698
]
@@ -107,4 +119,25 @@ public function search(): DataverseResponse
107119
$response->getBody()
108120
);
109121
}
122+
123+
public function search(): array
124+
{
125+
$responses = [];
126+
foreach ($this->getSearchUrls() as $url) {
127+
$responses[] = $this->executeRequest($url);
128+
}
129+
return $responses;
130+
}
131+
132+
public function count(): int
133+
{
134+
$total = 0;
135+
foreach ($this->search() as $response) {
136+
$body = json_decode($response->getBody(), true);
137+
if (isset($body['data']['total_count'])) {
138+
$total += $body['data']['total_count'];
139+
}
140+
}
141+
return $total;
142+
}
110143
}

report/services/DataverseReportService.inc.php

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

107-
$response = $searchBuilder->search();
108-
$data = json_decode($response->getBody(), true);
109-
return $data['data']['total_count'];
107+
return $searchBuilder->count();
110108
}
111109

112110
public function getDataverseSearchBuilder(int $contextId): DataverseSearchBuilder
Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,40 @@
11
<?php
22

33
import('plugins.generic.dataverse.dataverseAPI.search.DataverseSearchBuilder');
4+
import('plugins.generic.dataverse.classes.dataverseConfiguration.DataverseConfiguration');
45

56
class DataverseSearchBuilderTest extends PHPUnit\Framework\TestCase
67
{
8+
private const DATAVERSE_URL = 'https://test.dataverse.org/dataverse/testDataverse';
9+
private const SEARCH_URL = 'https://test.dataverse.org/api/search?';
10+
711
private function getDataverseSearchBuilder(): DataverseSearchBuilder
812
{
913
$configuration = new DataverseConfiguration();
1014
$httpClient = new \GuzzleHttp\Client();
1115

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

1418
return new DataverseSearchBuilder($configuration, $httpClient);
1519
}
1620

1721
public function testEmptyQuery(): void
1822
{
1923
$searchBuilder = $this->getDataverseSearchBuilder();
20-
$this->assertEquals('q=*', $searchBuilder->getParams());
24+
$this->assertEquals(
25+
[self::SEARCH_URL . 'q=*'],
26+
$searchBuilder->getSearchUrls()
27+
);
2128
}
2229

2330
public function testSingleQuery(): void
2431
{
2532
$searchBuilder = $this->getDataverseSearchBuilder();
2633
$searchBuilder->addQuery('test');
27-
$this->assertEquals('q=test', $searchBuilder->getParams());
34+
$this->assertEquals(
35+
[self::SEARCH_URL . 'q=test'],
36+
$searchBuilder->getSearchUrls()
37+
);
2838
}
2939

3040
public function testMultipleQueries(): void
@@ -33,14 +43,20 @@ public function testMultipleQueries(): void
3343
->addQuery('title:test')
3444
->addQuery('language:English');
3545

36-
$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+
);
3750
}
3851

3952
public function testSingleType(): void
4053
{
4154
$searchBuilder = $this->getDataverseSearchBuilder();
4255
$searchBuilder->addType('dataset');
43-
$this->assertEquals('q=*&type=dataset', $searchBuilder->getParams());
56+
$this->assertEquals(
57+
[self::SEARCH_URL . 'q=*&type=dataset'],
58+
$searchBuilder->getSearchUrls()
59+
);
4460
}
4561

4662
public function testMultipleTypes(): void
@@ -49,14 +65,20 @@ public function testMultipleTypes(): void
4965
->addType('dataset')
5066
->addType('file');
5167

52-
$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+
);
5372
}
5473

5574
public function testSingleFilterQuery(): void
5675
{
5776
$searchBuilder = $this->getDataverseSearchBuilder();
5877
$searchBuilder->addFilterQuery('publicationDate', '2016');
59-
$this->assertEquals('q=*&fq=publicationDate:2016', $searchBuilder->getParams());
78+
$this->assertEquals(
79+
[self::SEARCH_URL . 'q=*&fq=publicationDate:2016'],
80+
$searchBuilder->getSearchUrls()
81+
);
6082
}
6183

6284
public function testMultipleFilterQueries(): void
@@ -65,7 +87,10 @@ public function testMultipleFilterQueries(): void
6587
->addFilterQuery('publicationDate', '2016')
6688
->addFilterQuery('publicationStatus', 'Published');
6789

68-
$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+
);
6994
}
7095

7196
public function testFullParamsSearch(): void
@@ -76,22 +101,24 @@ public function testFullParamsSearch(): void
76101
->addFilterQuery('publicationStatus', 'Published');
77102

78103
$this->assertEquals(
79-
'q=foo&type=dataset&fq=publicationStatus:Published',
80-
$searchBuilder->getParams()
104+
[self::SEARCH_URL . 'q=foo&type=dataset&fq=publicationStatus:Published'],
105+
$searchBuilder->getSearchUrls()
81106
);
82107
}
83108

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

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

upgrade.xml

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

4-
<install version="2.8.9.0">
4+
<install version="2.8.9.1">
55
<migration
66
class="plugins.generic.dataverse.classes.migration.APITokenEncryptionMigration"
77
/>

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>2.8.9.0</release>
17-
<date>2026-05-11</date>
16+
<release>2.8.9.1</release>
17+
<date>2026-05-13</date>
1818
<lazy-load>1</lazy-load>
1919
<class>DataversePlugin</class>
2020
</version>

0 commit comments

Comments
 (0)