From e522639b9936cdc48fcfe2e51c26fe0d06460a1f Mon Sep 17 00:00:00 2001 From: datavoyager <jedimasterkenobi@hotmail.co.uk> Date: Wed, 5 Apr 2017 20:38:28 +0100 Subject: [PATCH] Add "author data" functionality to SolrDefault (#774) --- .../src/VuFind/RecordDriver/SolrDefault.php | 120 ++++++++++-------- .../Root/RecordDataFormatterFactory.php | 24 +++- .../SolrDefault/data-authors.phtml | 43 +++++-- 3 files changed, 121 insertions(+), 66 deletions(-) diff --git a/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php b/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php index e9ffad89c05..50f95a47c76 100644 --- a/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php +++ b/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php @@ -250,6 +250,51 @@ class SolrDefault extends AbstractBase return null; } + /** + * Get Author Information with Associated Data Fields + * + * @param string $index The author index [primary, corporate, or secondary] + * used to construct a method name for retrieving author data (e.g. + * getPrimaryAuthors). + * @param array $dataFields An array of fields to used to construct method + * names for retrieving author-related data (e.g., if you pass 'role' the + * data method will be similar to getPrimaryAuthorsRoles). This value will also + * be used as a key associated with each author in the resulting data array. + * + * @return array + */ + public function getAuthorDataFields($index, $dataFields = []) + { + $data = $dataFieldValues = []; + + // Collect author data + $authorMethod = sprintf('get%sAuthors', ucfirst($index)); + $authors = $this->tryMethod($authorMethod, [], []); + + // Collect attribute data + foreach ($dataFields as $field) { + $fieldMethod = $authorMethod . ucfirst($field) . 's'; + $dataFieldValues[$field] = $this->tryMethod($fieldMethod, [], []); + } + + // Match up author and attribute data (this assumes that the attribute + // arrays have the same indices as the author array; i.e. $author[$i] + // has $dataFieldValues[$attribute][$i]. + foreach ($authors as $i => $author) { + if (!isset($data[$author])) { + $data[$author] = []; + } + + foreach ($dataFieldValues as $field => $dataFieldValue) { + if (!empty($dataFieldValue[$i])) { + $data[$author][$field][] = $dataFieldValue[$i]; + } + } + } + + return $data; + } + /** * Get award notes for the record. * @@ -428,29 +473,23 @@ class SolrDefault extends AbstractBase * Deduplicate author information into associative array with main/corporate/ * secondary keys. * + * @param array $dataFields An array of extra data fields to retrieve (see + * getAuthorDataFields) + * * @return array */ - public function getDeduplicatedAuthors() - { - $authors = [ - 'main' => $this->getAuthorRolesArray( - $this->getPrimaryAuthors(), - $this->getPrimaryAuthorsRoles() - ), - 'corporate' => $this->getAuthorRolesArray( - $this->getCorporateAuthors(), - $this->getCorporateAuthorsRoles() - ), - 'secondary' => $this->getAuthorRolesArray( - $this->getSecondaryAuthors(), - $this->getSecondaryAuthorsRoles() - ) - ]; + public function getDeduplicatedAuthors($dataFields = ['role']) + { + $authors = []; + foreach (['primary', 'secondary', 'corporate'] as $type) { + $authors[$type] = $this->getAuthorDataFields($type, $dataFields); + }; // deduplicate $dedup = function (&$array1, &$array2) { if (!empty($array1) && !empty($array2)) { - foreach ($array1 as $author => $roles) { + $keys = array_keys($array1); + foreach ($keys as $author) { if (isset($array2[$author])) { $array1[$author] = array_merge( $array1[$author], @@ -462,52 +501,27 @@ class SolrDefault extends AbstractBase } }; - $dedup($authors['main'], $authors['corporate']); + $dedup($authors['primary'], $authors['corporate']); $dedup($authors['secondary'], $authors['corporate']); - $dedup($authors['main'], $authors['secondary']); + $dedup($authors['primary'], $authors['secondary']); - $dedup_roles = function (&$array) { - foreach ($array as $author => $roles) { - if (is_array($roles)) { - $array[$author] = array_unique($roles); + $dedup_data = function (&$array) { + foreach ($array as $author => $data) { + foreach ($data as $field => $values) { + if (is_array($values)) { + $array[$author][$field] = array_unique($values); + } } } }; - $dedup_roles($authors['main']); - $dedup_roles($authors['secondary']); - $dedup_roles($authors['corporate']); + $dedup_data($authors['primary']); + $dedup_data($authors['secondary']); + $dedup_data($authors['corporate']); return $authors; } - /** - * Helper function to restructure author arrays including relators - * - * @param array $authors Array of authors - * @param array $roles Array with relators of authors - * - * @return array - */ - protected function getAuthorRolesArray($authors = [], $roles = []) - { - $authorRolesArray = []; - - if (!empty($authors)) { - foreach ($authors as $index => $author) { - if (!isset($authorRolesArray[$author])) { - $authorRolesArray[$author] = []; - } - if (isset($roles[$index]) && !empty($roles[$index]) - ) { - $authorRolesArray[$author][] = $roles[$index]; - } - } - } - - return $authorRolesArray; - } - /** * Get the edition of the current record. * diff --git a/module/VuFind/src/VuFind/View/Helper/Root/RecordDataFormatterFactory.php b/module/VuFind/src/VuFind/View/Helper/Root/RecordDataFormatterFactory.php index 13934824dfc..f2da01a8434 100644 --- a/module/VuFind/src/VuFind/View/Helper/Root/RecordDataFormatterFactory.php +++ b/module/VuFind/src/VuFind/View/Helper/Root/RecordDataFormatterFactory.php @@ -198,10 +198,16 @@ class RecordDataFormatterFactory [ 'useCache' => true, 'labelFunction' => function ($data) { - return count($data['main']) > 1 + return count($data['primary']) > 1 ? 'Main Authors' : 'Main Author'; }, - 'context' => ['type' => 'main', 'schemaLabel' => 'author'], + 'context' => [ + 'type' => 'primary', + 'schemaLabel' => 'author', + 'requiredDataFields' => [ + ['name' => 'role', 'prefix' => 'CreatorRoles::'] + ] + ] ] ); $spec->setTemplateLine( @@ -212,7 +218,13 @@ class RecordDataFormatterFactory return count($data['corporate']) > 1 ? 'Corporate Authors' : 'Corporate Author'; }, - 'context' => ['type' => 'corporate', 'schemaLabel' => 'creator'], + 'context' => [ + 'type' => 'corporate', + 'schemaLabel' => 'creator', + 'requiredDataFields' => [ + ['name' => 'role', 'prefix' => 'CreatorRoles::'] + ] + ] ] ); $spec->setTemplateLine( @@ -220,7 +232,11 @@ class RecordDataFormatterFactory [ 'useCache' => true, 'context' => [ - 'type' => 'secondary', 'schemaLabel' => 'contributor' + 'type' => 'secondary', + 'schemaLabel' => 'contributor', + 'requiredDataFields' => [ + ['name' => 'role', 'prefix' => 'CreatorRoles::'] + ] ], ] ); diff --git a/themes/bootstrap3/templates/RecordDriver/SolrDefault/data-authors.phtml b/themes/bootstrap3/templates/RecordDriver/SolrDefault/data-authors.phtml index c63f6c6274e..d5e934703ba 100644 --- a/themes/bootstrap3/templates/RecordDriver/SolrDefault/data-authors.phtml +++ b/themes/bootstrap3/templates/RecordDriver/SolrDefault/data-authors.phtml @@ -1,15 +1,40 @@ <? - $formatRoles = function ($roles) { - if (count($roles) == 0) { - return ''; +$formatProperty = function ($datafield, $name, $label) { + if (count($datafield) == 0) { + return ''; } $that = $this; - $translate = function ($str) use ($that) { - return $that->transEsc('CreatorRoles::' . $str); + $translate = function ($str) use ($that, $label) { + return $that->transEsc($label . $str); }; - return ' (' . implode(', ', array_unique(array_map($translate, $roles))) . ')'; - }; + return '<span class="author-property-' . $name . '">(' . implode(', ', array_unique(array_map($translate, $datafield))) . ')</span>'; +}; +$formattedAuthors = []; ?> -<? if (isset($data[$type]) && !empty($data[$type])): ?> - <? $i = 0; foreach ($data[$type] as $author => $roles): ?><?=($i++ == 0)?'':', '?><span property="<?=$this->escapeHtml($schemaLabel)?>"><a href="<?=$this->record($this->driver)->getLink('author', $author)?>"><?=$this->escapeHtml($author)?></a><?=$formatRoles($roles)?></span><? endforeach; ?> +<? if (!empty($data[$type])): ?> + <? foreach ($data[$type] as $author => $dataFields): ?> + <? ob_start(); ?> + <span class="author-data" property="<?=$this->escapeHtml($schemaLabel)?>"> + <a href="<?=$this->record($this->driver)->getLink('author', $author)?>"> + <?=$this->escapeHtml($author)?> + </a> + <? + // Display additional data using the appropriate translation prefix + // (for example, to render author roles correctly): + foreach ($requiredDataFields as $field) { + $name = $field['name']; + $prefix = isset($field['prefix']) ? $field['prefix'] : ''; + if (isset($dataFields[$name])) { + echo $formatProperty($dataFields[$name], $name, $prefix); + } + } + ?> + </span> + <? + // Strip whitespace before close tags to avoid spaces in front of commas: + $formattedAuthors[] = trim(preg_replace('/\s+<\//', '</', ob_get_contents())); + ob_end_clean(); + ?> + <? endforeach; ?> <? endif; ?> +<?=implode(', ', $formattedAuthors)?> -- GitLab