From c451c38c730ccd4cd0801d5a4cfb002840cace6e Mon Sep 17 00:00:00 2001
From: jpkanter <kanter@ub.uni-leipzig.de>
Date: Mon, 11 Apr 2022 13:06:09 +0200
Subject: [PATCH] refs #21623 [finc] separated citavi and endnote export, added
 small format mapper for citavi export, probably not 100% coverage as of now

* extended citavi export format, needed to touch SolrMarcFincTrait to add getPages()
* added volume function to finctrait
---
 local/config/vufind/config.ini                |   1 +
 local/config/vufind/export.ini                |  11 +-
 .../finc/RecordDriver/SolrMarcFincTrait.php   |  38 +++
 .../AbstractBase/export-citavi.phtml          | 232 ++++++++++++++++++
 4 files changed, 281 insertions(+), 1 deletion(-)
 create mode 100644 themes/finc/templates/RecordDriver/AbstractBase/export-citavi.phtml

diff --git a/local/config/vufind/config.ini b/local/config/vufind/config.ini
index a7c4da375e3..882f6a16dbb 100644
--- a/local/config/vufind/config.ini
+++ b/local/config/vufind/config.ini
@@ -1160,6 +1160,7 @@ era             = true      ; allow browsing of era subdivisions
 [Export]
 RefWorks = false
 EndNote = "record,bulk"
+Citavi = "record,bulk"
 EndNoteWeb = false
 MARC = false
 MARCXML = false
diff --git a/local/config/vufind/export.ini b/local/config/vufind/export.ini
index dacbc2e5a71..5c5729f8387 100644
--- a/local/config/vufind/export.ini
+++ b/local/config/vufind/export.ini
@@ -32,7 +32,16 @@
 ;     cannot be implemented in a user-friendly way when Javascript is disabled.
 
 [EndNote]
-label = "Citavi/EndNote"
+label = "EndNote"
+requiredMethods[] = getTitle
+headers[] = "Pragma: public"
+headers[] = "Expires: Thu, 01 Dec 1994 16:00:00 GMT"
+headers[] = "Cache-Control: must-revalidate, post-check=0, pre-check=0, private"
+headers[] = "Content-type: application/x-endnote-refer"
+headers[] = "Content-Disposition: attachment; filename=\"vufind.enw\";"
+
+[Citavi]
+label = "Citavi"
 requiredMethods[] = getTitle
 headers[] = "Pragma: public"
 headers[] = "Expires: Thu, 01 Dec 1994 16:00:00 GMT"
diff --git a/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php b/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php
index 5c5d72a3143..ec33cb04f36 100644
--- a/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php
+++ b/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php
@@ -2089,6 +2089,25 @@ trait SolrMarcFincTrait
         return $this->getFirstFieldValue('245', ['n']);
     }
 
+    /**
+     * Gets the volume number of an article inside a bigger volumen, only if 936 exists
+     *
+     * @return mixed
+     */
+    public function getContainerVolume()
+    {
+        $field = $this->getMarcRecord()->getFields('936');
+        if ($field) {
+            foreach ( $field as $each ) {
+                $subfield = $each->getSubfield('d');
+                if ($subfield) {
+                    return $subfield->getData();
+                }
+            }
+        }
+        return null;
+    }
+
     /**
      * Get Cartographic Mathematical Data
      *
@@ -2640,4 +2659,23 @@ trait SolrMarcFincTrait
         }
         return null;
     }
+
+    /**
+     * Returns Start and Endpage of an Article inside a bigger release
+     *
+     * @return mixed
+     */
+    public function getPages()
+    {
+        $field = $this->getMarcRecord()->getFields('936');
+        if ($field) {
+            foreach ( $field as $each ) {
+                $subfield = $each->getSubfield('h');
+                if ($subfield) {
+                    return $subfield->getData();
+                }
+            }
+        }
+        return null;
+    }
 }
diff --git a/themes/finc/templates/RecordDriver/AbstractBase/export-citavi.phtml b/themes/finc/templates/RecordDriver/AbstractBase/export-citavi.phtml
new file mode 100644
index 00000000000..d70fbc1bbd2
--- /dev/null
+++ b/themes/finc/templates/RecordDriver/AbstractBase/export-citavi.phtml
@@ -0,0 +1,232 @@
+<?php
+// per https://www1.citavi.com/sub/manual5/en/importing_an_endnote_tagged_file.html
+// also for germans: https://www.ub.rwth-aachen.de/global/show_document.asp?id=aaaaaaaaaaptikv&download=1
+$filter = new Zend\Filter\Word\CamelCaseToSeparator();
+// A driver-specific template may pass in format overrides; check for these before going to the driver itself:
+$formats = isset($this->overrideFormats) ? $this->overrideFormats : $this->driver->tryMethod('getFormats');
+if (is_array($formats) && !empty($formats)) {
+  foreach ($formats as $format) {
+    switch ($format) {
+      case 'Article':
+      case 'ElectronicArticle':
+      case 'SerialComponentPart':
+      case 'ElectronicSerialComponentPart':
+        $format = "Journal article";
+        break;
+      case 'BookComponentPart':
+        $format = "Book Section";
+        break;
+      case 'ElectronicBookComponentPart':
+      case 'ElectronicBookPart':
+        $format = "Contribution in an Edited Book";
+        break;
+        case 'ElectronicBook':
+      case 'eBook':
+        $format = "Electronic Book";
+        break;
+      default:
+        //$format = $format;  // unnecessary default
+        break;
+    }
+    $format = $filter->filter($format);
+    echo "%0 $format\n";
+  }
+} else {
+  // Assume book if no format found (otherwise data may be considered invalid):
+  echo "%0 Book\n";
+}
+/*$author = $this->driver->tryMethod('getPrimaryAuthor');
+if (!empty($author)) {
+    echo "%A $author\n";
+}
+$authors = $this->driver->tryMethod('getAdditionalAuthors');
+if (!empty($authors)) {
+    $arr = [];
+    foreach ($authors as $author) {
+        $arr[] = $author['name'];
+    }
+    $author = implode(' and ', $arr);
+    echo "%A $author\n";
+}*/
+
+$authors = [];
+$primaryAuthor = $this->driver->tryMethod('getPrimaryAuthor');
+if (!empty($primaryAuthor)) {
+  $authors[] = $primaryAuthor;
+}
+$additionalAuthors = $this->driver->tryMethod('getAdditionalAuthors');
+if (!empty($additionalAuthors)) {
+  $authors[] = $additionalAuthors;
+}
+if (!empty($authors)) {
+  $arr = [];
+  foreach ($authors as $author) {
+    if (is_array($author)) {
+      foreach ($author as $au) {
+        if (!in_array($au['name'], $arr)) {
+          $arr[] = $au['name'];
+        }
+      }
+    } else {
+      if (!in_array($author, $arr)) {
+        $arr[] = $author;
+      }
+    }
+  }
+  $author = implode(' and ', $arr);
+  echo "%A {$author}\n";
+}
+
+$secondaryAuthors = $this->driver->tryMethod('getSecondaryAuthors');
+if (is_array($secondaryAuthors)) {
+  foreach ($secondaryAuthors as $current) {
+    echo "%E $current\n";
+  }
+}
+
+$pubPlaces = $this->driver->tryMethod('getPlacesOfPublication');
+$pubDates = $this->driver->tryMethod('getPublicationDates');
+$pubNames = $this->driver->tryMethod('getPublishers');
+if (is_array($pubPlaces) && is_array($pubDates) && is_array($pubNames)) {
+  $total = min(count($pubPlaces), count($pubDates), count($pubNames));
+  // if we have pub dates but no other details, we still want to export the year:
+  if ($total == 0 && (
+      (count($pubDates) > 0)
+      || (count($pubNames) > 0)
+      || (count($pubPlaces) > 0)
+    )) {
+    $total = 1;
+  }
+  for ($i = 0; $i < $total; $i++) {
+    if (isset($pubNames[$i])) {
+      echo "%I " . rtrim($pubNames[$i], ", ") . "\n";
+    }
+    if (isset($pubDates[$i])) {
+      $date = trim($pubDates[$i], '[]. ');
+      if (strlen($date) > 4) {
+        $date = $this->dateTime()->extractYear($date);
+      }
+      /*if ($date) {
+        echo "%D $date\n";
+      } */ /* TODO: decide if this is really superfluous */
+    }
+    if (isset($pubPlaces[$i])) {
+      echo "%C " . rtrim(str_replace(array('[', ']'), '', $pubPlaces[$i]), ': ') . "\n";
+    }
+  }
+}
+
+// echo "%C ?\n";
+
+$data = $this->driver->tryMethod('getPublishedIn');
+if (isset($data['date'])) {
+  $date = $data['date'];
+  echo "%D {$date}\n";
+}
+
+if (empty($data)) {
+  $date = $this->driver->tryMethod('getPublishDateSort');
+  if (!empty($date)) {
+    echo "%D {$date}\n";
+  }
+}
+
+$languages = $this->driver->tryMethod('getLanguages');
+if (is_array($languages)) {
+  foreach ($languages as $lang) {
+    echo "%G $lang\n";
+  }
+}
+
+$series = $this->driver->tryMethod('getSeries');
+if (is_array($series)) {
+  foreach ($series as $current) {
+    echo '%B ' . (is_array($current) ? $current['name'] : $current) . "\n";
+  }
+}
+
+$isbns = $this->driver->tryMethod('getISBNs');
+if (is_array($isbns)) {
+  foreach ($isbns as $isbn) {
+    echo "%@ $isbn\n";
+  }
+}
+
+$issns = $this->driver->tryMethod('getISSNs');
+if (is_array($issns)) {
+  foreach ($issns as $issn) {
+    echo "%@ $issn\n";
+  }
+}
+
+$library = $this->config()->get('config')->Site->title;
+if (!empty($library)) {
+  echo "%~ {$library}\n";
+}
+
+$title = rtrim($this->driver->getTitle(), " /");
+echo "%T $title\n";
+
+$volume = $this->driver->tryMethod('getVolume');
+if (!empty($volume)) {
+  $volume = str_replace(',', '', $volume);
+  echo "%V $volume\n";
+}
+
+$journalTitle = $this->driver->tryMethod('getContainerTitle');
+if (!empty($journalTitle)) {
+  echo "%J $journalTitle\n";
+  $volume = $this->driver->tryMethod('getContainerVolume');
+  if (!empty($volume)) {
+    echo "%V $volume\n";
+  }
+  $number = $this->driver->tryMethod('getContainerIssue');
+  if (!empty($number)) {
+    echo "%N $number\n";
+  }
+  /* getContainerStartPage is not implemented in default and will give '' */
+  /*$page = $this->driver->tryMethod('getContainerStartPage');
+  if (!empty($page)) {
+      $end = $this->driver->tryMethod('getContainerEndPage');
+      if (!empty($end) && $end != $page) {
+          $page .= '-' . $end;
+      }
+      echo "%P $page\n";
+  }*/
+  $pages = $this->driver->tryMethod('getPages');
+  if (!empty($pages)) {
+    // use page range if possible
+    if (!empty($pages)) {
+      echo "%P {$pages}\n";
+    }
+  }
+}
+
+foreach ($this->record($this->driver)->getUrlList() as $doi) {
+  echo "%U $doi\n";
+}
+
+$edition = $this->driver->tryMethod('getEdition');
+if (!empty($edition)) {
+  echo "%7 $edition\n";
+}
+
+$summary = $this->driver->tryMethod('getSummary');
+if (!empty($summary)) {
+  echo "%X {$summary[0]}\n";
+}
+
+$serverurl = $this->serverUrl();
+$url = $serverurl . $this->url('record', ['id' => $this->driver->getUniqueId()]);
+if (!empty($url)) {
+  echo "%Z {$url}\n";
+}
+
+$serverurl = $this->serverUrl();
+$url = $serverurl . $this->url('record', ['id' => $this->driver->getUniqueId()]);
+if (!empty($url)) {
+  echo "%U {$url}\n";
+}
+// Record separator:
+echo "\n";
+?>
\ No newline at end of file
-- 
GitLab