Skip to content

Commit

Permalink
Improved RIS export (#3954)
Browse files Browse the repository at this point in the history
  • Loading branch information
damien-git authored Oct 10, 2024
1 parent cc4060b commit 25a3825
Show file tree
Hide file tree
Showing 7 changed files with 374 additions and 25 deletions.
19 changes: 18 additions & 1 deletion module/VuFind/src/VuFind/RecordDriver/DefaultRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,23 @@ public function getAllSubjectHeadings($extended = false)
return array_map($callback, array_unique($headings));
}

/**
* Get the subject headings as a flat array of strings.
*
* @return array Subject headings
*/
public function getAllSubjectHeadingsFlattened()
{
$headings = [];
$subjects = $this->getAllSubjectHeadings();
if (is_array($subjects)) {
foreach ($subjects as $subj) {
$headings[] = implode(' -- ', $subj);
}
}
return $headings;
}

/**
* Get all record links related to the current record. Each link is returned as
* array.
Expand Down Expand Up @@ -243,7 +260,7 @@ public function getCallNumber()
*/
public function getCallNumbers()
{
return (array)($this->fields['callnumber-raw'] ?? []);
return array_unique((array)($this->fields['callnumber-raw'] ?? []));
}

/**
Expand Down
27 changes: 20 additions & 7 deletions module/VuFind/src/VuFind/RecordDriver/EDS.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ public function getItemsAbstract()
return $abstract[0]['Data'] ?? '';
}

/**
* Get the abstract notes.
* For EDS, returns the abstract in an array or an empty array.
*
* @return array
*/
public function getAbstractNotes()
{
$abstract = $this->getItems(null, null, 'Ab');
return (array)($abstract[0]['Data'] ?? []);
}

/**
* Get the access level of the record.
*
Expand Down Expand Up @@ -431,19 +443,20 @@ public function getLinkedFullTextLink()
}

/**
* Get the subject data of the record.
* Get the subject headings as a flat array of strings.
*
* @return string
* @return array Subject headings
*/
public function getItemsSubjects()
public function getAllSubjectHeadingsFlattened()
{
$subjects = array_map(
$subject_arrays = array_map(
function ($data) {
return $data['Data'];
$str = preg_replace('/>\s*[;,]\s*</', '>|<', $data['Data']);
return explode('|', rtrim(strip_tags($str), '.'));
},
$this->getItems(null, null, 'Su')
);
return empty($subjects) ? '' : implode(', ', $subjects);
return array_merge(...$subject_arrays);
}

/**
Expand Down Expand Up @@ -682,7 +695,7 @@ public function getCleanDOI()
{
$doi = $this->getItems(null, null, null, 'DOI');
if (isset($doi[0]['Data'])) {
return $doi[0]['Data'];
return strip_tags($doi[0]['Data']);
}
$dois = $this->getFilteredIdentifiers(['doi']);
return $dois[0] ?? false;
Expand Down
136 changes: 126 additions & 10 deletions module/VuFind/src/VuFind/RecordDriver/Feature/MarcAdvancedTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -558,16 +558,6 @@ protected function getSeriesFromMARC($fieldInfo)
return $matches;
}

/**
* Get an array of summary strings for the record.
*
* @return array
*/
public function getSummary()
{
return $this->getFieldArray('520');
}

/**
* Get an array of technical details on the item represented by the record.
*
Expand Down Expand Up @@ -1170,4 +1160,130 @@ public function getTextualHoldings()
{
return $this->getFieldArray('866');
}

/**
* Check if an array of indicator filters match the provided marc data
*
* @param array $marc_data MARC data for a specific field
* @param array $indFilter Array with up to 2 keys ('1', and '2') with an array as their value
* containing what to match on in the marc indicator.
* ex: ['1' => ['0','1']] would filter ind1 with 0 or 1
*
* @return bool
*/
protected function checkIndicatorFilter($marc_data, $indFilter): bool
{
foreach (range(1, 2) as $indNum) {
if (isset($indFilter[$indNum])) {
if (!in_array(trim(($marc_data['i' . $indNum] ?? '')), (array)$indFilter[$indNum])) {
return false;
}
}
}
// If we got this far, no non-matching filters were encountered.
return true;
}

/**
* Check if the indicator filters match the provided marc data
*
* @param array $marc_data MARC data for a specific field
* @param array $indData Indicator filters as described in getMarcFieldWithInd()
*
* @return bool
*/
protected function checkIndicatorFilters($marc_data, $indData): bool
{
foreach ($indData as $indFilter) {
if ($this->checkIndicatorFilter($marc_data, $indFilter)) {
return true;
}
}
// If we got this far, either $indData is empty (no filters defined -- return true)
// or it is non-empty (no filters matched -- return false)
return empty($indData);
}

/**
* Takes a Marc field that notes are stored in (ex: 950) and a list of
* sub fields (ex: ['a','b']) optionally as well as what indicator
* numbers and values to filter for and concatenates the subfields
* together and returns the fields back as an array
* (ex: ['subA subB subC', 'field2SubA field2SubB'])
*
* @param string $field Marc field to search within
* @param ?array $subfield Sub-fields to return or empty for all
* @param array $indData Array of filter arrays, each in the format indicator number =>
* array of allowed indicator values. If any one of the filter arrays fully matches the indicator
* values in the field, data will be returned. If no filter arrays are defined, data will always
* be returned regardless of indicators.
* ex: [['1' => ['1', '2']], ['2' => ['']]] would filter fields ind1 = 1 or 2 or ind2 = blank
* ex: [['1' => ['1'], '2' => ['7']]] would filter fields with ind1 = 1 and ind2 = 7
* ex: [] would apply no filtering based on indicators
*
* @return array The values within the subfields under the field
*/
public function getMarcFieldWithInd(
string $field,
?array $subfield = null,
array $indData = []
) {
$vals = [];
$marc = $this->getMarcReader();
$marc_fields = $marc->getFields($field, $subfield);
foreach ($marc_fields as $marc_data) {
$field_vals = [];
if ($this->checkIndicatorFilters($marc_data, $indData)) {
$subfields = $marc_data['subfields'];
foreach ($subfields as $subfield) {
$field_vals[] = $subfield['data'];
}
}
$newVal = implode(' ', $field_vals);
if (!empty($field_vals) && !in_array($newVal, $vals)) {
$vals[] = $newVal;
}
}
return $vals;
}

/**
* Get the location of other archival materials notes
*
* @return array Note fields from the MARC record
*/
public function getLocationOfArchivalMaterialsNotes()
{
return $this->getMarcFieldWithInd('544', range('a', 'z'), [[1 => ['', '0']]]);
}

/**
* Get an array of summary strings for the record with only the 'a' subfield.
*
* @return array
*/
public function getSummary()
{
return $this->getMarcFieldWithInd('520', ['a'], [[1 => ['', '0', '2', '8']]]);
}

/**
* Get the summary note
*
* @return array Note fields from the MARC record
*/
public function getSummaryNotes()
{
return $this->getMarcFieldWithInd('520', range('a', 'z'), [[1 => ['', '0', '2', '8']]]);
}

/**
* Get the abstract notes
*
* @return array Note fields from the MARC record
*/
public function getAbstractNotes()
{
return $this->getMarcFieldWithInd('520', range('a', 'z'), [[1 => ['3']]]);
}
}
16 changes: 16 additions & 0 deletions module/VuFind/tests/fixtures/marc/marctraits.xml
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,28 @@
<subfield code="a">Summary.</subfield>
<subfield code="b">Expanded.</subfield>
</datafield>
<datafield tag="520" ind1="1" ind2=" ">
<subfield code="a">Review Note.</subfield>
<subfield code="b">Expanded.</subfield>
<subfield code="1">http://expanded.</subfield>
</datafield>
<datafield tag="520" ind1="3" ind2=" ">
<subfield code="a">Abstract.</subfield>
<subfield code="b">Expanded.</subfield>
</datafield>
<datafield tag="520" ind1="4" ind2=" ">
<subfield code="a">Content Advice.</subfield>
<subfield code="b">Expanded.</subfield>
</datafield>
<datafield tag="521" ind1=" " ind2=" ">
<subfield code="a">Developers</subfield>
</datafield>
<datafield tag="538" ind1=" " ind2=" ">
<subfield code="a">Data in UTF-8</subfield>
</datafield>
<datafield tag="544" ind1=" " ind2=" ">
<subfield code="a">Location of archival materials</subfield>
</datafield>
<datafield tag="555" ind1="0" ind2=" ">
<subfield code="a">Finding aid available</subfield>
</datafield>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -564,17 +564,19 @@ public function testGetLinkedFullTextLink(): void
}

/**
* Test getItemsSubjects for a record.
* Test getAllSubjectHeadingsFlattened for a record.
*
* @return void
*/
public function testGetItemsSubjects(): void
public function testGetAllSubjectHeadingsFlattened(): void
{
$driver = $this->getDriver('valid-eds-record');
$this->assertEquals(
'<a href="../EDS/Search?lookfor=%22PSYCHOTHERAPY%22&amp;type=SU">PSYCHOTHERAPY</a>, ' .
'<a href="../EDS/Search?lookfor=%22METAPHOR%2E%22&amp;type=SU">METAPHOR.</a>',
$driver->getItemsSubjects()
[
'PSYCHOTHERAPY',
'METAPHOR',
],
$driver->getAllSubjectHeadingsFlattened()
);
}

Expand Down
Loading

0 comments on commit 25a3825

Please sign in to comment.