Last active
April 3, 2023 15:03
-
-
Save dmj/9a79e92e216d15aa74a472004efdd379 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SUBHH\VuFind\RecordDescription; | |
use SUBHH\VuFind\SolrMarc\SolrMarc; | |
interface DescriptionProviderInterface | |
{ | |
/** @return array<string, DisplayValueInterface[]> */ | |
public function createDescription (SolrMarc $record) : array; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SUBHH\VuFind\RecordDescription; | |
class DisplayValue implements DisplayValueInterface | |
{ | |
/** @var string */ | |
private $value; | |
/** @var ?string */ | |
private $prefix; | |
/** @var ?string */ | |
private $suffix; | |
/** @var ?string */ | |
private $textdomain = null; | |
/** @var bool */ | |
private $translatable = false; | |
public function __construct (string $value) | |
{ | |
$this->value = $value; | |
} | |
public function isTranslatable () : bool | |
{ | |
return $this->translatable; | |
} | |
public function setIsTranslatable (bool $translatable) : void | |
{ | |
$this->translatable = $translatable; | |
} | |
public function setTextDomain (string $textdomain = null) : void | |
{ | |
$this->textdomain = $textdomain; | |
} | |
public function getTextDomain () : ?string | |
{ | |
return $this->textdomain; | |
} | |
public function getValue () : string | |
{ | |
return $this->value; | |
} | |
public function getSuffix () : ?string | |
{ | |
return $this->suffix; | |
} | |
public function getPrefix () : ?string | |
{ | |
return $this->prefix; | |
} | |
public function setSuffix (string $suffix) : void | |
{ | |
$this->suffix = $suffix; | |
} | |
public function setPrefix (string $prefix) : void | |
{ | |
$this->prefix = $prefix; | |
} | |
public function __toString () : string | |
{ | |
return $this->getValue(); | |
} | |
public static function newInstance (string $value, bool $isTranslatable = false) : DisplayValue | |
{ | |
$value = new DisplayValue($value); | |
$value->setIsTranslatable($isTranslatable); | |
return $value; | |
} | |
/** | |
* @param string[] $values | |
* @return DisplayValue[] | |
*/ | |
public static function newInstances (array $values, bool $isTranslatable = false) : array | |
{ | |
$instances = array(); | |
foreach ($values as $value) { | |
$instances[] = static::newInstance($value, $isTranslatable); | |
} | |
return $instances; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SUBHH\VuFind\RecordDescription; | |
interface DisplayValueInterface | |
{ | |
public function isTranslatable () : bool; | |
public function getValue () : string; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SUBHH\VuFind\RecordDescription; | |
use ArrayIterator; | |
use Iterator; | |
class DisplayValueSequence implements DisplayValueInterface | |
{ | |
/** @var DisplayValueInterface[] */ | |
private $members = array(); | |
/** @var string */ | |
private $separator; | |
public function __construct (string $separator = ' ') | |
{ | |
$this->separator = $separator; | |
} | |
public function append (DisplayValueInterface $member) : void | |
{ | |
$this->members[] = $member; | |
} | |
public function getIterator () : Iterator | |
{ | |
return new ArrayIterator($this->members); | |
} | |
public function getSeparator () : string | |
{ | |
return $this->separator; | |
} | |
public function isTranslatable () : bool | |
{ | |
return false; | |
} | |
public function getValue () : string | |
{ | |
$values = array(); | |
foreach ($this->members as $member) { | |
$values[] = $member->getValue(); | |
} | |
return implode($this->getSeparator(), $values); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SUBHH\VuFind\RecordDescription; | |
final class ExternalLink extends DisplayValue | |
{ | |
/** @var string */ | |
private $linkTarget; | |
/** @var ?string */ | |
private $linkLabel; | |
public function __construct (string $linkTarget) | |
{ | |
parent::__construct($linkTarget); | |
$this->linkTarget = $linkTarget; | |
} | |
public function getLinkTarget () : string | |
{ | |
return $this->linkTarget; | |
} | |
public function getLinkLabel () : ?string | |
{ | |
return $this->linkLabel; | |
} | |
public function setLinkLabel (string $linkLabel) : void | |
{ | |
$this->linkLabel = $linkLabel; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SUBHH\VuFind\RecordDescription; | |
use SUBHH\VuFind\SolrMarc\SolrMarc; | |
use VuFind\Marc\MarcReader; | |
use UnexpectedValueException; | |
class FullDescriptionProvider implements DescriptionProviderInterface | |
{ | |
/** @return array<string, DisplayValueInterface[]> */ | |
public function createDescription (SolrMarc $record) : array | |
{ | |
$reader = $record->getMarcReader(); | |
$description = array(); | |
$description['Title'] = [$this->getTitle($reader)]; | |
$description['Identifier'] = [new DisplayValue($record->getUniqueID())]; | |
$description['Preceding Title'] = $this->getPrecedingTitle($reader); | |
$description['Succeeding Title'] = $this->getSucceedingTitle($reader); | |
$description['Title Variant'] = $this->getTitleVariant($reader); | |
$description['Work Title'] = $this->getUniformTitle($reader); | |
$description['Summary'] = $this->getSummary($reader); | |
$description['Persons'] = $this->getPersons($reader); | |
$description['Corporate Bodies'] = $this->getCorporateBody($reader); | |
$description['Congresses'] = $this->getCongresses($reader); | |
$description['Media Type'] = DisplayValue::newInstances($record->getFormats(), true); | |
$description['Form Note'] = $this->getFormNote($reader); | |
$description['Language'] = $this->getLanguages($reader); | |
$description['Extent'] = DisplayValue::newInstances($reader->getFieldsSubfields('300', ['a', 'b', 'c', 'e'])); | |
$description['Published'] = $this->getPublicationStatement($reader); | |
$description['Containing Work'] = $this->getHostItem($reader); | |
$description['Included Items'] = $this->getIncludedItems($reader); | |
$description['Edition'] = DisplayValue::newInstances($reader->getFieldsSubfields('250', ['a'], null)); | |
$description['Note'] = DisplayValue::newInstances($reader->getFieldsSubfields('500', ['a'], null)); | |
$description['Bibliographic Context'] = $this->getBibliographicContext($reader); | |
$description['Basisklassifikation'] = $this->getKeywordsBKL($reader); | |
$description['RVK'] = $this->getKeywordsRVK($reader); | |
$description['Other Classifications'] = $this->getOtherClassifications($reader); | |
$description['Keywords'] = $this->getKeywords($reader); | |
$description['Links'] = $this->getExternalLinks($reader); | |
$description['ISBN'] = $this->getIsbn($reader); | |
$description['ISSN'] = $this->getIssn($reader); | |
$description['Series'] = $this->getSeries($reader); | |
return array_filter($description); | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getFormNote (MarcReader $reader) : array | |
{ | |
$notes = array(); | |
foreach ($reader->getFieldsSubfields('655', ['a', 'b', 'v', 'x', 'y', 'z'], ' ; ') as $value) { | |
$notes[] = new DisplayValue($value); | |
} | |
return $notes; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getOtherClassifications (MarcReader $reader) : array | |
{ | |
$classes = array(); | |
foreach ($reader->getFields('983') as $field) { | |
if ($reader->getSubfield($field, '2') === '22') { | |
if ($value = $reader->getSubfield($field, 'a')) { | |
$value = new SearchLink($value); | |
$value->setSearchType('Subject'); | |
$value->setSearchTerm($value); | |
$classes[] = $value; | |
} | |
} | |
} | |
return $classes; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getBibliographicContext (MarcReader $reader) : array | |
{ | |
$context = array(); | |
foreach ($reader->getFields('776') as $field) { | |
if ($title = $reader->getSubfield($field, 't')) { | |
$value = new SearchLink($title); | |
$this->annotateRelatedSearchLink($reader, $field, $value); | |
if ($prefix = array_filter($this->getSubfields($field, 'i', 'n'))) { | |
$value->setPrefix(implode(' ', $prefix) . ': '); | |
} | |
if ($suffix = $reader->getSubfield($field, 'd')) { | |
$value->setSuffix(' – ' . $suffix); | |
} | |
$context[] = $value; | |
} | |
} | |
return $context; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getUniformTitle (MarcReader $reader) : array | |
{ | |
$titles = array(); | |
foreach ($reader->getFields('240') as $field) { | |
if ($title = $reader->getSubfield($field, 'a')) { | |
$value = new DisplayValueSequence(); | |
$title = new SearchLink($title); | |
$title->setSearchTerm($title); | |
$title->setSearchTermQuote('"'); | |
$value->append($title); | |
if ($authorField = $this->getDataField($reader, '100')) { | |
if ($name = $reader->getSubfield($authorField, 'a')) { | |
$value->append(new DisplayValue($name)); | |
$rolecode = $reader->getSubfield($field, '4') ?: 'oth'; | |
$role = new DisplayValue($rolecode); | |
$role->setPrefix('['); | |
$role->setSuffix(']'); | |
$role->setIsTranslatable(true); | |
$role->setTextDomain('CreatorRoles'); | |
$value->append($role); | |
} | |
} | |
$titles[] = $value; | |
} | |
} | |
return $titles; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getPrecedingTitle (MarcReader $reader) : array | |
{ | |
$titles = array(); | |
foreach ($reader->getFields('780') as $field) { | |
if ($title = $reader->getSubfield($field, 't')) { | |
$value = new SearchLink($title); | |
$this->annotateRelatedSearchLink($reader, $field, $value); | |
$titles[] = $value; | |
} | |
} | |
return $titles; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getSucceedingTitle (MarcReader $reader) : array | |
{ | |
$titles = array(); | |
foreach ($reader->getFields('785') as $field) { | |
if ($title = $reader->getSubfield($field, 't')) { | |
$value = new SearchLink($title); | |
$this->annotateRelatedSearchLink($reader, $field, $value); | |
$titles[] = $value; | |
} | |
} | |
return $titles; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getHostItem (MarcReader $reader) : array | |
{ | |
$hosts = array(); | |
foreach ($reader->getFields('773') as $field) { | |
$title = $reader->getSubfield($field, 't') ?: implode($reader->getFieldsSubfields('245', ['a'])); | |
if ($title) { | |
list($relationship, $pubinfo, $parts) = $this->getSubfields($field, 'i', 'd', 'g'); | |
$value = new SearchLink($title); | |
if ($relationship) { | |
$value->setPrefix($relationship . ': '); | |
} | |
if ($pubinfo || $parts) { | |
if ($pubinfo && $parts) { | |
$value->setSuffix('.- ' . $pubinfo . ', ' . $parts); | |
} else { | |
$value->setSuffix('.- ' . $pubinfo . $parts); | |
} | |
} | |
$this->annotateRelatedSearchLink($reader, $field, $value); | |
$hosts[] = $value; | |
} | |
} | |
return $hosts; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getCongresses (MarcReader $reader) : array | |
{ | |
$congresses = array(); | |
foreach ($reader->getFields('111') as $field) { | |
list($name, $date, $place) = $this->getSubfields($field, 'a', 'd', 'c'); | |
if ($name) { | |
if ($date) { | |
$name .= ', ' . $date; | |
} | |
if ($place) { | |
$name .= ', ' . $place; | |
} | |
$congress = new SearchLink($name); | |
$congress->setSearchType('Title'); | |
$congresses[] = $congress; | |
} | |
} | |
return $congresses; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getIncludedItems (MarcReader $reader) : array | |
{ | |
$items = array_merge( | |
DisplayValue::newInstances($reader->getFieldsSubfields('501', ['a'], null)), | |
DisplayValue::newInstances($reader->getFieldsSubfields('505', ['a'], null)) | |
); | |
return $items; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getSeries (MarcReader $reader) : array | |
{ | |
$series = array(); | |
$fields = array_merge( | |
$reader->getFields('830') | |
); | |
foreach ($fields as $field) { | |
if ($label = $reader->getSubfield($field, 'a')) { | |
$value = new SearchLink($label); | |
$this->annotateRelatedSearchLink($reader, $field, $value); | |
if ($volume = $reader->getSubfield($field, 'v')) { | |
$value->setSuffix(' - ' . $volume); | |
} | |
$series[] = $value; | |
} | |
} | |
return $series; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getExternalLinks (MarcReader $reader) : array | |
{ | |
$links = array(); | |
foreach ($reader->getFields('856') as $field) { | |
if ($field['i2'] === '2') { | |
if ($linkTarget = $reader->getSubfield($field, 'u')) { | |
$link = new ExternalLink($linkTarget); | |
$description = implode(' ', $this->getSubfields($field, '3', 'z')); | |
$link->setLinkLabel($description ?: $linkTarget); | |
$links[] = $link; | |
} | |
} | |
} | |
return $links; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getCorporateBody (MarcReader $reader) : array | |
{ | |
$corporations = array(); | |
$fields = array_merge( | |
[$this->getDataField($reader, '110')], | |
$reader->getFields('710') | |
); | |
foreach ($fields as $field) { | |
if ($name = $reader->getSubfield($field, 'a')) { | |
$value = new DisplayValueSequence(); | |
$corporation = new SearchLink($name); | |
$corporation->setSearchTermQuote('"'); | |
$corporation->setSearchType('Person'); | |
$value->append($corporation); | |
if ($date = $reader->getSubfield($field, 'd')) { | |
$value->append(new DisplayValue($date)); | |
} | |
$rolecode = $reader->getSubfield($field, '4') ?: 'oth'; | |
$role = new DisplayValue($rolecode); | |
$role->setPrefix('['); | |
$role->setSuffix(']'); | |
$role->setIsTranslatable(true); | |
$role->setTextDomain('CreatorRoles'); | |
$value->append($role); | |
$corporations[] = $value; | |
} | |
} | |
return $corporations; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getPublicationStatement (MarcReader $reader) : array | |
{ | |
$publicationStatements = array(); | |
foreach ($reader->getFields('264') as $field) { | |
list($place, $publisher, $date) = $this->getSubfields($field, 'a', 'b', 'c'); | |
$statement = $place; | |
if ($place && ($publisher || $date)) { | |
$statement .= ': '; | |
} | |
if ($publisher) { | |
$statement .= $publisher; | |
} | |
if ($publisher && $date) { | |
$statement .= ' '; | |
} | |
if ($date) { | |
$statement .= $date; | |
} | |
if ($statement) { | |
$publicationStatements[] = new DisplayValue($statement); | |
} | |
} | |
foreach ($reader->getFields('501') as $field) { | |
$publicationStatements[] = new DisplayValue($reader->getSubfield($field, 'a')); | |
} | |
return $publicationStatements; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getKeywords (MarcReader $reader) : array | |
{ | |
$keywords = array(); | |
$fields = array_merge( | |
$reader->getFields('600'), | |
$reader->getFields('610'), | |
$reader->getFields('630'), | |
$reader->getFields('650'), | |
$reader->getFields('651'), | |
); | |
foreach ($fields as $field) { | |
if ($main = $reader->getSubfield($field, 'a')) { | |
$main = array_merge( | |
[$main], | |
$reader->getSubfields($field, 'z'), | |
$reader->getSubfields($field, 'x'), | |
$reader->getSubfields($field, 'y'), | |
); | |
$term = implode(', ', $main); | |
$keyword = new SearchLink($term); | |
$keyword->setSearchTerm($term); | |
$keyword->setSearchTermQuote('"'); | |
$keyword->setSearchType('Subject'); | |
$keywords[] = $keyword; | |
} | |
} | |
$keywords = array_merge($keywords, $this->getKeywordChain($reader)); | |
return $keywords; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getKeywordChain (MarcReader $reader) : array | |
{ | |
$keywords = array(); | |
$fields = array(); | |
foreach ($reader->getFields('689') as $field) { | |
if (ctype_digit($field['i1']) && ctype_digit($field['i2'])) { | |
$index = intval($field['i1']); | |
$pos = intval($field['i2']); | |
$term = $reader->getSubfield($field, 'a'); | |
$member = new SearchLink($term); | |
$member->setSearchTerm('"' . addcslashes($term, '"') . '"'); | |
$member->setSearchType('Subject'); | |
$fields[$index][$pos] = $member; | |
} | |
} | |
ksort($fields); | |
foreach ($fields as $members) { | |
$chain = new DisplayValueSequence(' / '); | |
foreach ($members as $member) { | |
$chain->append($member); | |
} | |
$keywords[] = $chain; | |
} | |
return $keywords; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getKeywordsRVK (MarcReader $reader) : array | |
{ | |
$keywords = array(); | |
foreach ($reader->getFields('936') as $field) { | |
if ($field['i1'] === 'r' && $field['i2'] === 'v') { | |
if ($term = $reader->getSubfield($field, 'a')) { | |
if ($label = $reader->getSubfield($field, 'b')) { | |
$label = $term . ' / ' . $label; | |
} else { | |
$label = $term; | |
} | |
$keyword = new SearchLink($label); | |
$keyword->setSearchTerm($term); | |
$keyword->setSearchType('Class'); | |
if ($suffix = $reader->getSubfields($field, 'k')) { | |
$keyword->setSuffix(' [' . implode(', ', $suffix) . ']'); | |
} | |
$keywords[] = $keyword; | |
} | |
} | |
} | |
return $keywords; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getKeywordsBKL (MarcReader $reader) : array | |
{ | |
$keywords = array(); | |
foreach ($reader->getFields('936') as $field) { | |
if ($field['i1'] === 'b' && $field['i2'] === 'k') { | |
if ($term = $reader->getSubfield($field, 'a')) { | |
$label = array_filter($this->getSubfields($field, 'a', 'j', 'x')); | |
$keyword = new SearchLink(implode(' ', $label)); | |
$keyword->setSearchTerm($term); | |
$keyword->setSearchType('BK'); | |
$keywords[] = $keyword; | |
} | |
} | |
} | |
return $keywords; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getPersons (MarcReader $reader) : array | |
{ | |
$persons = array(); | |
$fields = array_merge( | |
[$this->getDataField($reader, '100')], | |
$reader->getFields('700') | |
); | |
foreach ($fields as $field) { | |
if ($name = $reader->getSubfield($field, 'a')) { | |
$value = new DisplayValueSequence(); | |
$person = new SearchLink($name); | |
$person->setSearchType('Person'); | |
$person->setSearchTermQuote('"'); | |
$value->append($person); | |
if ($date = $reader->getSubfield($field, 'd')) { | |
$value->append(new DisplayValue($date)); | |
} | |
$rolecode = $reader->getSubfield($field, '4') ?: 'oth'; | |
$role = new DisplayValue($rolecode); | |
$role->setPrefix('['); | |
$role->setSuffix(']'); | |
$role->setIsTranslatable(true); | |
$role->setTextDomain('CreatorRoles'); | |
$value->append($role); | |
$persons[] = $value; | |
} | |
} | |
return $persons; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getLanguages (MarcReader $reader) : array | |
{ | |
$languages = array(); | |
foreach ($reader->getFieldsSubfields('041', ['a'], null) as $code) { | |
$language = new DisplayValue($code); | |
$language->setIsTranslatable(true); | |
$languages[] = $language; | |
} | |
return $languages; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getSummary (MarcReader $reader) : array | |
{ | |
return DisplayValue::newInstances($reader->getFieldsSubfields('520', ['a'], null)); | |
} | |
/** @return DisplayValue */ | |
private function getTitle (MarcReader $reader) : DisplayValue | |
{ | |
// Note: 245 is non-repeatable | |
if ($field = $this->getDataField($reader, '245')) { | |
$title = $reader->getSubfield($field, 'a'); | |
if ($subtitle = $reader->getSubfield($field, 'b')) { | |
$title .= ' : ' . $subtitle; | |
} | |
if ($medium = $reader->getSubfield($field, 'h')) { | |
$title .= ' / ' . $medium; | |
} | |
foreach ($field['subfields'] as $subfield) { | |
if ($subfield['code'] === 'n') { | |
$title .= ' / ' . $subfield['data']; | |
} | |
if ($subfield['code'] === 'p') { | |
$title .= ', ' . $subfield['data']; | |
} | |
} | |
if ($resp = $reader->getSubfield($field, 'c')) { | |
$title .= ' : ' . $resp; | |
} | |
return new DisplayValue($title); | |
} | |
return new DisplayValue('no title'); | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getTitleVariant (MarcReader $reader) : array | |
{ | |
$titles = array(); | |
foreach ($reader->getFields('246') as $field) { | |
if ($field['i2'] !== '3') { | |
if ($title = $reader->getSubfield($field, 'a')) { | |
$value = new DisplayValue($title); | |
$titles[] = $value; | |
} | |
} | |
} | |
return $titles; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getIssn (MarcReader $reader) : array | |
{ | |
$issns = array(); | |
foreach ($reader->getFields('022') as $field) { | |
if ($issn = $reader->getSubfield($field, 'a')) { | |
$value = new SearchLink($issn); | |
$value->setSearchType('ISN'); | |
$value->setSearchTerm($value); | |
$issns[] = $value; | |
} | |
} | |
return $issns; | |
} | |
/** @return DisplayValueInterface[] */ | |
private function getIsbn (MarcReader $reader) : array | |
{ | |
$isbns = array(); | |
foreach ($reader->getFields('020') as $field) { | |
list($isbn, $label) = $this->getSubfields($field, 'a', '9'); | |
if ($isbn) { | |
$value = new SearchLink($label ?: $isbn); | |
$value->setSearchType('ISN'); | |
$value->setSearchTerm($isbn); | |
$isbns[] = $value; | |
} | |
} | |
return $isbns; | |
} | |
// private function getControlField (MarcReader $reader, string $tag) : ?string | |
// { | |
// $field = $reader->getField($tag); | |
// if ($field) { | |
// if (is_array($field)) { | |
// throw new UnexpectedValueException(); | |
// } | |
// return $field; | |
// } | |
// return null; | |
// } | |
/** @return array<mixed> */ | |
private function getDataField (MarcReader $reader, string $tag) : array | |
{ | |
$field = $reader->getField($tag); | |
if ($field && !is_array($field)) { | |
throw new UnexpectedValueException(); | |
} | |
return (array)$field; | |
} | |
/** | |
* @param array<mixed> $field | |
* @return string[] | null[] | |
*/ | |
private function getSubfields (array $field, string ...$codes) : array | |
{ | |
$values = array_fill(0, count($codes), null); | |
foreach ($field['subfields'] as $subfield) { | |
$key = array_search($subfield['code'], $codes, true); | |
if ($key !== false) { | |
$values[$key] = $subfield['data']; | |
unset($codes[$key]); | |
} | |
} | |
return $values; | |
} | |
private function annotateRelatedSearchLink (MarcReader $reader, array $field, SearchLink $value) : void | |
{ | |
foreach ($reader->getSubfields($field, 'w') as $id) { | |
if (str_starts_with($id, '(DE-627)')) { | |
$value->setSearchTerm((string)substr($id, 8)); | |
$value->setSearchType('Id'); | |
return; | |
} | |
} | |
foreach ($reader->getSubfields($field, 'w') as $id) { | |
if (str_starts_with($id, '(DE-600)')) { | |
$value->setSearchTerm('(DE-599)ZDB' . (string)substr($id, 8)); | |
$value->setSearchType('Numbers'); | |
$value->setSearchTermQuote('"'); | |
return; | |
} | |
} | |
if ($issn = $reader->getSubfield($field, 'x')) { | |
$value->setSearchTerm($issn); | |
$value->setSearchType('Isn'); | |
return; | |
} | |
$value->setSearchType('Title'); | |
$value->setSearchTermQuote('"'); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SUBHH\VuFind\RecordDescription; | |
final class ResourceLocator | |
{ | |
public static function getResourceDirectory () : string | |
{ | |
return __DIR__ . '/../../resources/subhh-vufind-recorddescription'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SUBHH\VuFind\RecordDescription; | |
class SearchLink extends DisplayValue | |
{ | |
/** @var ?string */ | |
private $searchTerm; | |
/** @var string */ | |
private $searchType = 'AllFields'; | |
/** @var ?string */ | |
private $searchTermQuote = null; | |
public function getSearchTerm () : string | |
{ | |
if (is_string($this->searchTerm)) { | |
if ($this->searchTermQuote) { | |
return $this->searchTermQuote . addcslashes($this->searchTerm, $this->searchTermQuote) . $this->searchTermQuote; | |
} | |
return $this->searchTerm; | |
} | |
return $this->getValue(); | |
} | |
public function getSearchType () : string | |
{ | |
return $this->searchType; | |
} | |
public function setSearchTerm (string $searchTerm) : void | |
{ | |
$this->searchTerm = $searchTerm; | |
} | |
public function setSearchType (string $searchType) : void | |
{ | |
$this->searchType = $searchType; | |
} | |
public function setSearchTermQuote (string $searchTermQuote = null) : void | |
{ | |
$this->searchTermQuote = $searchTermQuote; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SUBHH\VuFind\RecordDescription; | |
use SUBHH\VuFind\SolrMarc\SolrMarc; | |
use VuFind\Marc\MarcReader; | |
use UnexpectedValueException; | |
class ShortDescriptionProvider implements DescriptionProviderInterface | |
{ | |
/** @return array<string, DisplayValueInterface[]> */ | |
public function createDescription (SolrMarc $record) : array | |
{ | |
$reader = $record->getMarcReader(); | |
$description = array(); | |
$description['Title'] = new DisplayValue($record->getTitle()); | |
$description['Creator'] = $this->getPersons($reader); | |
$description['Publication'] = $this->getPublicationStatement($reader); | |
return array_filter($description); | |
} | |
private function getPersons (MarcReader $reader) : ?DisplayValueInterface | |
{ | |
if ($field = $this->getDataField($reader, '100')) { | |
if ($name = $reader->getSubfield($field, 'a')) { | |
$person = new SearchLink($name); | |
$person->setSearchTerm($name); | |
$person->setSearchType('Person'); | |
$person->setSearchTermQuote('"'); | |
return $person; | |
} | |
} | |
return null; | |
} | |
private function getPublicationStatement (MarcReader $reader) : ?DisplayValueInterface | |
{ | |
if ($field = $this->getDataField($reader, '264')) { | |
list($place, $publisher, $date) = $this->getSubfields($field, 'a', 'b', 'c'); | |
$statement = $place; | |
if ($place && ($publisher || $date)) { | |
$statement .= ': '; | |
} | |
if ($publisher) { | |
$statement .= $publisher; | |
} | |
if ($publisher && $date) { | |
$statement .= ' '; | |
} | |
if ($date) { | |
$statement .= $date; | |
} | |
if ($statement) { | |
return new DisplayValue($statement); | |
} | |
} | |
return null; | |
} | |
/** @return array<mixed> */ | |
private function getDataField (MarcReader $reader, string $tag) : array | |
{ | |
$field = $reader->getField($tag); | |
if ($field && !is_array($field)) { | |
throw new UnexpectedValueException(); | |
} | |
return (array)$field; | |
} | |
/** | |
* @param array<mixed> $field | |
* @return string[] | null[] | |
*/ | |
private function getSubfields (array $field, string ...$codes) : array | |
{ | |
$values = array_fill(0, count($codes), null); | |
foreach ($field['subfields'] as $subfield) { | |
$key = array_search($subfield['code'], $codes, true); | |
if ($key !== false) { | |
$values[$key] = $subfield['data']; | |
unset($codes[$key]); | |
} | |
} | |
return $values; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SUBHH\VuFind\RecordDescription; | |
use SUBHH\VuFind\SolrMarc\SolrMarc; | |
use Laminas\View\Helper\AbstractHelper; | |
final class ViewHelper extends AbstractHelper | |
{ | |
/** @var DescriptionProviderInterface */ | |
private $provider; | |
public function __construct (DescriptionProviderInterface $provider) | |
{ | |
$this->provider = $provider; | |
} | |
public function renderDisplayValue (DisplayValueInterface $value) : ?string | |
{ | |
$view = $this->getView(); | |
if ($view) { | |
switch (get_class($value)) { | |
case SearchLink::class: | |
return $view->render('SearchLink', ['value' => $value]); | |
case ExternalLink::class: | |
return $view->render('ExternalLink', ['value' => $value]); | |
case DisplayValueSequence::class: | |
return $view->render('DisplayValueSequence', ['sequence' => $value]); | |
case DisplayValue::class: | |
return $view->render('DisplayValue', ['value' => $value]); | |
default: | |
return $view->render('DisplayValueInterface', ['value' => $value]); | |
} | |
} | |
return null; | |
} | |
/** @return array<string, DisplayValueInterface[]> */ | |
public function getDescription (SolrMarc $record) : array | |
{ | |
return $this->provider->createDescription($record); | |
} | |
public function __invoke () : self | |
{ | |
return $this; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment