diff options
| author | Philipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de> | 2024-09-24 10:53:31 +0200 |
|---|---|---|
| committer | Philipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de> | 2024-09-24 10:53:31 +0200 |
| commit | 4459dd7917f4d1c34f40bb68f0e991e9c3d53e4c (patch) | |
| tree | 5c07151ae61276d334e88f6309c30d439a85c12e /lib/classes/librarysearch/LibraryDocument.php | |
| parent | da0022e5c1abbf9825ae76debaabdff7e8623bb4 (diff) | |
| parent | 97a188592c679890a25c37ab78463add76a52ff7 (diff) | |
Merge branch 'main' into issue-3911issue-3911
Diffstat (limited to 'lib/classes/librarysearch/LibraryDocument.php')
| -rw-r--r-- | lib/classes/librarysearch/LibraryDocument.php | 442 |
1 files changed, 442 insertions, 0 deletions
diff --git a/lib/classes/librarysearch/LibraryDocument.php b/lib/classes/librarysearch/LibraryDocument.php new file mode 100644 index 0000000..c1d297e --- /dev/null +++ b/lib/classes/librarysearch/LibraryDocument.php @@ -0,0 +1,442 @@ +<?php +/** + * This file is part of Stud.IP. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * @author Moritz Strohm <strohm@data-quest.de> + * @copyright 2020 + * @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2 + * @category Stud.IP + * @since 4.6 + */ + +/** + * This class represents a document from a library. + */ +class LibraryDocument +{ + /** + * An unique ID of the document. + */ + public $id = ''; + + + /** + * The OPAC ID of the document. + */ + public $opac_document_id = ''; + + + /** + * The link to the document page in the OPAC system. + */ + public $opac_link = ''; + + + /** + * The CSL document type. + */ + public $type = ''; + + + /** + * The CSL datafields. + */ + public $csl_data = []; + + + /** + * The name of the catalog from which the document has been retrieved. + */ + public $catalog = ''; + + + /** + * Other data that cannot be stored in the $csl_data array. + */ + public $datafields; + + + /** + * The search parameter that have been used to retrieve this item. + */ + public $search_params = []; + + + /** + * Generates an ID for the document. + */ + public function getId() + { + if (!$this->id) { + $this->id = md5(uniqid('LibraryDocument' . $this->getTitle())); + } + return $this->id; + } + + + /** + * Returns the type of the document as string. + * + * @returns string The type of the document. + */ + public function getType($format = 'name'): string + { + global $LIBRARY_DOCUMENT_TYPES; + + if ($format === 'name') { + return $this->type; + } + if ($format === 'display_name') { + $ldt = SimpleCollection::createFromArray($LIBRARY_DOCUMENT_TYPES); + $found = $ldt->findOneBy('name', $this->type); + $lang = in_array($_SESSION['_language'], ['de_DE', 'en_GB']) ? $_SESSION['_language'] : 'de_DE'; + if ($found) { + return $found['display_name'][$lang]; + } + } + + return ''; + } + + + /** + * Returns the title of the document as string. + * + * @param string $format The format of the title. + * 'short' means that only the title is returned. + * 'long' means that the author, the year and the title are + * concatenated into one string. + * 'long-comma' means that the author, the title and the year + * are concatenated in that order, only separated by a comma. + * + * @returns string The title of the document. + */ + public function getTitle($format = 'short'): string + { + if ($format == 'long') { + $long_title = ''; + if (isset($this->csl_data['issued'], $this->csl_data['author'])) { + $first_author_last_name = $this->csl_data['author'][0]['family']; + $year = $this->getIssueDate(true); + if ($year) { + $long_title = sprintf('%1$s (%2$s) - ', $first_author_last_name, $year); + } else { + $long_title = sprintf('%s - ', $first_author_last_name); + } + } elseif (isset($this->csl_data['author'])) { + $first_author_last_name = $this->csl_data['author'][0]['family']; + $long_title = sprintf('%s - ', $first_author_last_name); + } + $long_title .= $this->csl_data['title'] ?? ''; + return $long_title; + } elseif ($format == 'long-comma') { + $data = []; + $first_author_last_name = trim($this->csl_data['author'][0]['family']); + $year = trim($this->getIssueDate(true)); + if ($first_author_last_name) { + $data[] = $first_author_last_name; + } + $data[] = $this->csl_data['title'] ?? ''; + if ($year) { + $data[] = $year; + } + return implode(', ', $data); + } else { + return $this->csl_data['title'] ?? ''; + } + } + + + /** + * @returns string A list with all author names. + */ + public function getAuthorNames(): string + { + if (empty($this->csl_data['author'])) { + return ''; + } + + $names = []; + foreach ($this->csl_data['author'] as $author) { + $names[] = sprintf('%1$s, %2$s', $author['family'], $author['given']); + } + return implode('; ', $names); + } + + + /** + * Returns a string with the issue date. + * + * @param bool $year_only Whether to return only the year of the date (true) + * or the whole date (false). Defaults to false. + * + * @returns string A string representing the issue date. + */ + public function getIssueDate($year_only = false): string + { + if (!$this->csl_data['issued']) { + return ''; + } + if ($year_only) { + $year = @$this->csl_data['issued']['date-parts'][0][0]; + return $year ?: ''; + } + return implode('-', $this->csl_data['issued']['date-parts'][0]) ?: ''; + } + + + /** + * @returns string A string with identifiers of the document (ISBN, URL, ...). + */ + public function getIdentifiers(): string + { + $identifiers = []; + if ($this->csl_data['ISBN']) { + $identifiers[] = sprintf(_('ISBN: %s'), $this->csl_data['ISBN']); + } + if ($this->csl_data['ISSN']) { + $identifiers[] = sprintf(_('ISSN: %s'), $this->csl_data['ISSN']); + } + return implode('; ', $identifiers); + } + + + /** + * Filters the CSL data fields by the document type. + * Only those CSL fields that are specified in library_config.inc.php for + * the document type are kept. + */ + public function filterCslFieldsByType() + { + if (!$this->type) { + return; + } + + $doc_type_config = null; + foreach ($GLOBALS['LIBRARY_DOCUMENT_TYPES'] as $doc_config) { + if ($doc_config['name'] == $this->type) { + $doc_type_config = $doc_config; + break; + } + } + if ($doc_type_config == null) { + return; + } + $this->csl_data = array_filter( + $this->csl_data, + function ($field) use ($doc_type_config) { + return in_array($field, $doc_type_config['properties']); + }, + ARRAY_FILTER_USE_KEY + ); + } + + + /** + * Converts this LibraryDocument to an associative array. + * + * @returns array An associative array containing the data of this + * LibraryDocument instance. + */ + public function toArray(): array + { + $data = [ + 'id' => $this->getId(), + 'type' => $this->getType(), + 'csl_data' => $this->csl_data, + 'datafields' => $this->datafields, + 'search_params' => $this->search_params, + 'catalog' => $this->catalog, + 'opac_link' => $this->opac_link + ]; + return $data; + } + + + /** + * Converts this LibraryDocument to JSON data. + * + * @returns string A string containing the JSON encoded version of this + * LibraryDocument instance. + */ + public function toJson(): string + { + return json_encode($this->toArray()); + } + + + /** + * Fills or creates empty or missing CSL data fields that may be required + * when rendering the CSL data. + * + * @returns array The "enriched" CSL data from this document. + */ + public function fillEmptyCslFields(): array + { + $enriched_data = []; + foreach ($this->csl_data as $key => $field) { + if ($key == 'author') { + if (!$field[0]['family']) { + $field[0]['family'] = ' '; + } + } + $enriched_data[$key] = $field; + } + //Make sure all "mandatory" fields are there: + if (!array_key_exists('author', $enriched_data)) { + $enriched_data['author'] = [ + [ + 'given' => '', + 'family' => ' ', + 'suffix' => '' + ] + ]; + } + return $enriched_data; + } + + + /** + * Creates a LibraryDocument instance from an associative array. + * + * @param array $data An associative array containing data for + * a LibraryDocument instance. + * + * @returns LibraryDocument|null A LibraryDocument instance on success + * or null on failure. + */ + public static function createFromArray(array $data = []) + { + if (!$data) { + return null; + } + $doc = new LibraryDocument(); + $doc->id = $data['id']; + $doc->type = $data['type']; + $doc->csl_data = $data['csl_data']; + $doc->datafields = $data['datafields']; + $doc->search_params = $data['search_params']; + $doc->catalog = $data['catalog'] ?? null; + $doc->opac_link = $data['opac_link'] ?? null; + return $doc; + } + + + /** + * Creates a LibraryDocument instance from JSON data. + * + * @param string $json_string A JSON string containing data for + * a LibraryDocument instance. + * + * @returns LibraryDocument|null A LibraryDocument instance on success + * or null on failure. + */ + public static function createFromJson(string $json_string = "") + { + if (!$json_string) { + return null; + } + $data = json_decode($json_string); + if (!$data) { + return null; + } + return self::createFromArray($data); + } + + + /** + * Determines if this document is equal to another document. + * Equality is determined by comparing various ID fields + * and as a last resort, the title, author and year are compared. + * + * @param LibraryDocument $other Another library document that shall be + * compared to this document. + * + * @returns bool True, if this document is equal to the other document, + * false otherwise. + */ + public function isEqualTo(LibraryDocument $other): bool + { + if ($this->type != $other->type) { + //No need to do any further checks. + return false; + } + if ($this->id && ($this->id == $other->id)) { + return true; + } elseif ($this->csl_data['ISSN'] && ($this->csl_data['ISSN'] == $other->csl_data['ISSN'])) { + return true; + } elseif ($this->csl_data['ISBN'] && ($this->csl_data['ISBN'] == $other->csl_data['ISBN'])) { + return true; + } elseif ($this->csl_data['DOI'] && ($this->csl_data['DOI'] == $other->csl_data['DOI'])) { + return true; + } elseif ($this->csl_data['title'] && $this->csl_data['author'] && $this->csl_data['issued'] + && ($this->csl_data['title'] == $other->csl_data['title']) + && ($this->csl_data['author'] == $other->csl_data['author']) + && ($this->csl_data['issued'] == $other->csl_data['issued'])) { + return true; + } + return false; + } + + + /** + * @returns Flexi\Template A template containing information about the + * the document. + */ + public function getInfoTemplate($format = 'short') + { + $factory = new Flexi\Factory( + $GLOBALS['STUDIP_BASE_PATH'] . '/templates/library/' + ); + $template = $factory->open('library_document_info'); + $template->set_attribute('document', $this); + $template->set_attribute('format', $format); + return $template; + } + + + /** + * Creates a descriptive text of the search parameters that lead to the + * retrieval of this document. + * + * @returns string[] An array with a textual representation of all + * used search parameters. + */ + public function getSearchDescription() + { + $description = []; + if (isset($this->search_params[LibrarySearch::AUTHOR])) { + $description[] = sprintf(_('Autor: „%s“'), $this->search_params[LibrarySearch::AUTHOR]); + } + if (isset($this->search_params[LibrarySearch::YEAR])) { + $description[] = sprintf(_('Jahr: „%s“'), $this->search_params[LibrarySearch::YEAR]); + } + if (isset($this->search_params[LibrarySearch::TITLE])) { + $description[] = sprintf(_('Titel: „%s“'), $this->search_params[LibrarySearch::TITLE]); + } + if (isset($this->search_params[LibrarySearch::NUMBER])) { + $description[] = sprintf(_('Nummer: „%s“'), $this->search_params[LibrarySearch::NUMBER]); + } + if (isset($this->search_params[LibrarySearch::PUBLICATION])) { + $description[] = sprintf(_('Zeitschrift: „%s“'), $this->search_params[LibrarySearch::PUBLICATION]); + } + if (isset($this->search_params[LibrarySearch::SIGNATURE])) { + $description[] = sprintf(_('Signatur: „%s“'), $this->search_params[LibrarySearch::SIGNATURE]); + } + return $description; + } + + public function getIcon() + { + global $LIBRARY_DOCUMENT_TYPES; + $ldt = SimpleCollection::createFromArray($LIBRARY_DOCUMENT_TYPES); + $found = $ldt->findOneBy('name', $this->type); + $shape = $found['icon'] ?? 'literature-request'; + return Icon::create($shape); + } +} |
