From 1438c110e245f37de4de3310a8e3f59aa7b22383 Mon Sep 17 00:00:00 2001
From: Frank Morgner <morgnerf@ub.uni-leipzig.de>
Date: Thu, 11 Apr 2019 15:26:38 +0200
Subject: [PATCH] refs #14439 [master-v5] - replaces BSZ pattern by new DE-627
 kxp pattern for link related items of title * replaces BSZ_PATTERN with
 KXP_PATTERN * necessary refactoring of method getOtherRelationsshipEntry() *
 keep lookup for Solr for checking if item of related record really exists in
 Solr infrastructure * legacy mode with rewrite back Solr record_id in return
 container; could be diverge use of different contexts

---
 .../RecordDriver/SolrDefaultFincTrait.php     |  52 +++++---
 .../src/finc/RecordDriver/SolrMarcFinc.php    |   7 ++
 .../finc/RecordDriver/SolrMarcFincTrait.php   | 113 ++++++------------
 .../data-otherRelationshipEntry.phtml         |  10 +-
 4 files changed, 87 insertions(+), 95 deletions(-)

diff --git a/module/finc/src/finc/RecordDriver/SolrDefaultFincTrait.php b/module/finc/src/finc/RecordDriver/SolrDefaultFincTrait.php
index 31bdebc6a98..7deda8b564e 100644
--- a/module/finc/src/finc/RecordDriver/SolrDefaultFincTrait.php
+++ b/module/finc/src/finc/RecordDriver/SolrDefaultFincTrait.php
@@ -76,6 +76,17 @@ trait SolrDefaultFincTrait
         */
     }
 
+    /**
+     * Has children
+     *
+     * @return bool
+     * @access public
+     * @link https://projekte.ub.uni-leipzig.de/issues/14742
+     */
+    public function hasChildren() {
+        return parent::isCollection();
+    }
+
     /**
      * Get all call numbers associated with the record (empty string if none).
      *
@@ -806,15 +817,23 @@ trait SolrDefaultFincTrait
     }
 
     /**
-     * After giving a record ids as e.g. ppn of the BSZ check if a record exists.
-     * This method can be used to indicate a direct link than to form a general
-     * look for query.
+     * After giving a record ids as e.g. ppn of the context check (KXP|BSZ) if a
+     * foreign record exists. This method can be used to indicate a direct link
+     * than to form a general look for query.
      *
-     * @param array $array Array of record ids to test.
+     * Please note: 1) This method can be simplified if it is necessary only to
+     * map record_id to id but you need the solr to check if the item really
+     * exists in the Solr infrastructure to maybe no displaying a false link later
+     * on. 2) There's legacy component to rewrite back real Solr record_id in
+     * return container. Can be useful if there are still any successive methods
+     * in action.
      *
-     * @return int mixed  If success return at least one finc id otherwise null.
+     * @param array  $array Array of record ids to test.
+     * @param string $context Context where to search related items.
+     *
+     * @return null|mixed  If success return at least one finc id otherwise null.
      */
-    protected function addFincIDToRecord($array)
+    protected function addFincIDToRecord($array, $context = 'kxp_id_str')
     {
         // record ids
         $rids = [];
@@ -834,15 +853,18 @@ trait SolrDefaultFincTrait
             }
         }
 
+        // Solr query remains necessary if it is desired to check if solr
+        // infrastructure contains really the foreign items
+
         // build the query:
         if (count($rids) == 1) {
             // single query:
-            $value = 'record_id:' . $rids[0]['rid']
+            $value = $context . ':' . $rids[0]['rid']
                      . ' AND source_id:' . $rids[0]['sid'];
         } elseif (count($rids) > 1) {
             // multi query:
             foreach ($rids as $rid) {
-                $parts[] = '(record_id:' . $rid['rid']
+                $parts[] = '('. $context .':' . $rid['rid']
                            . ' AND source_id:' . $rid['sid'] . ')';
             }
             $value = '(' . implode(' OR ', $parts) . ')';
@@ -851,7 +873,7 @@ trait SolrDefaultFincTrait
         }
         $query = new \VuFindSearch\Query\Query($value);
         $bag = new ParamBag();
-        $bag->set('fl', 'id,record_id');
+        $bag->set('fl', 'id, record_id,' . $context);
         $records =  $this->searchService
             ->search('Solr', $query, 0, count($rids), $bag);
 
@@ -860,11 +882,10 @@ trait SolrDefaultFincTrait
             && !empty($records)
         ) {
             foreach ($records as $record) {
-                // we SHOULD use the immediate field values here since the
-                // above query yields record stubs of type VuFind\RecordDriver\SolrDefault
-                // which normally not allow for specialized functions e.g. SolrMarcFinc::getRID
-                // the specified fields, however, will always be set
-                $retval[$record->fields['record_id']] = $record->fields['id'];
+                $retval[$record->getField($context)]['id'] =
+                    $record->getUniqueID();
+                $retval[$record->getField($context)]['record_id'] =
+                    $record->getRID();
             }
         }
 
@@ -872,7 +893,8 @@ trait SolrDefaultFincTrait
         foreach ($array as &$val) {
             if (isset($val['record_id'])) {
                 if (isset($retval[($val['record_id'])])) {
-                    $val['id'] = $retval[($val['record_id'])];
+                    $val['id'] = $retval[($val['record_id'])]['id'];
+                    $val['record_id'] = $retval[($val['record_id'])]['record_id'];
                 }
             }
         }
diff --git a/module/finc/src/finc/RecordDriver/SolrMarcFinc.php b/module/finc/src/finc/RecordDriver/SolrMarcFinc.php
index 299e373a232..b61f4049ddf 100644
--- a/module/finc/src/finc/RecordDriver/SolrMarcFinc.php
+++ b/module/finc/src/finc/RecordDriver/SolrMarcFinc.php
@@ -44,9 +44,16 @@ class SolrMarcFinc extends SolrMarc
 
     /**
      * pattern to identify bsz
+     *
+     * @deprecated After k10plus transition maybe not longer in use.
      */
     const BSZ_PATTERN = '/^(\(DE-576\))(\d+)(\w|)/';
 
+    /**
+     * pattern to identify kxp
+     */
+    const KXP_PATTERN = '/^(\(DE-627\))(\d+)(\w|)/';
+
     /**
      * List of isil of institution
      *
diff --git a/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php b/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php
index fdc2aacbcdb..286b1dd7cc4 100644
--- a/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php
+++ b/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php
@@ -331,7 +331,7 @@ trait SolrMarcFincTrait
             foreach ($linkFields as $current) {
                 $text = $current->getData();
                 // Extract parenthetical prefixes:
-                if (preg_match(self::BSZ_PATTERN, $text, $matches)) {
+                if (preg_match(self::KXP_PATTERN, $text, $matches)) {
                     //$id = $this->checkIfRecordExists($matches[2]);
                     //if ($id != null) {
                     $array[$key]['record_id'] = $matches[2].$matches[3];
@@ -1086,7 +1086,7 @@ trait SolrMarcFincTrait
             foreach ($linkFields as $current) {
                 $text = $current->getData();
                 // Extract parenthetical prefixes:
-                if (preg_match(self::BSZ_PATTERN, $text, $matches)) {
+                if (preg_match(self::KXP_PATTERN, $text, $matches)) {
                     $array[$key]['record_id'] = $matches[2] . $matches[3];
                     if (null != ($sid = $this->getSourceID())) {
                         $array[$key]['source_id'] = $sid;
@@ -1125,84 +1125,47 @@ trait SolrMarcFincTrait
         $retval = [];
         $defaultHeading = 'Note';
         // container for collecting recordIDs to the result array #12941
-        $tempIds = [];
 
-        $fields = $this->getMarcRecord()->getFields('787');
-        if (!$fields) {
+        $entires = $this->getMarcRecord()->getFields('787');
+        if (!$entires) {
             return null;
         }
-        foreach ($fields as $field) {
+        foreach ($entires as $key => $line) {
             // don't do anything unless we have something in $a
-            if ($a = $field->getSubfield('a')) {
-                // do we have a main entry heading?
-                if ($i = $field->getSubfield('i')) {
-                    // build the text to be displayed from subfields $a and/or $t
-                    $text = ($t = $field->getSubfield('t'))
-                        ? $a->getData() . ': ' . $t->getData()
-                        : $a->getData();
-
-                    $linkFields = $field->getSubfields('w');
-                    foreach ($linkFields as $current) {
-                        $ids = $current->getData();
-
-                        // Extract parenthetical prefixes:
-                        if (preg_match(self::BSZ_PATTERN, $ids, $matches)) {
-                            // use the same key to set the record_id into the
-                            // $retval array like it is used for the other
-                            // content below
-                            $tempIds[$i->getData()]['record_id']
-                                = $matches[2] . $matches[3];
+            if ($a = $line->getSubfield('a')) {
+                $retval[$key]['subject'] = ($line->getSubfield('i'))
+                    ? $line->getSubfield('i')->getData() : $defaultHeading;
+                // build the text to be displayed from subfields $a and/or $t
+                $retval[$key]['text'] = ($t = $line->getSubfield('t'))
+                    ? $a->getData() . ': ' . $t->getData()
+                    : $a->getData();
+                $linkFields = $line->getSubfields('w');
+                foreach ($linkFields as $current) {
+                    $ids = $current->getData();
+
+                    // Extract parenthetical prefixes:
+                    if (preg_match(self::KXP_PATTERN, $ids, $matches)) {
+                        // use the same key to set the record_id into the
+                        // $retval array like it is used for the other
+                        // content below
+                        $retval[$key]['record_id']
+                            = $matches[2] . $matches[3];
+                        if (null != ($sid = $this->getSourceID())) {
+                            $retval[$key]['source_id'] = $sid;
                         }
-                    } // end foreach
-
-                    // add ids already here to the temporary array
-                    // instead of the end of the function with the return value
-                    $tempIds = $this->addFincIDToRecord($tempIds);
-
-                    // does a linked record exist
-                    $link = ($w = $field->getSubfield('w'))
-                        ? $w->getData() : '';
-
-                    // we expect the links to be ppns prefixed with an ISIL so
-                    // strip the ISIL
-                    $ppn = preg_replace(
-                        "/^\(([A-z])+\-([A-z0-9])+\)\s?/",
-                        "",
-                        $link
-                    );
-
-                    $record_id = null;
-                    if (!empty($tempIds[$i->getData()]['id'])) {
-                        $record_id = $tempIds[$i->getData()]['record_id'];
-                    }
-
-                    $id = null;
-                    if (!empty($tempIds[$i->getData()]['id'])) {
-                        $id = $tempIds[$i->getData()]['id'];
                     }
-
-                    // let's use the main entry heading as associative key and
-                    // push the gathered content into the retval array
-                    // add recordIDs 'record_id' and 'id' to the result array
-                    // cmp. #12941
-                    $retval[$i->getData()][] = [
-                        'text' => $text,
-                        'link' => (!empty($ppn) ? $ppn : $link),
-                        'record_id' => $record_id,
-                        'id' => $id
-                    ];
-                } else {
-                    // no main entry heading found, so push subfield a's content
-                    // into retval using the defaultHeading
-                    $retval[$defaultHeading][] = [
-                        'text' => $a->getData(),
-                        'link' => ''
-                    ];
                 }
             }
         }
-
-        return $retval;
+        // add ids already here to the temporary array
+        // instead of the end of the function with the return value
+        $retval = $this->addFincIDToRecord($retval);
+        // rearrange return array to collect same subjects below on unique key
+        $array = [];
+        foreach ($retval as $item) {
+            $array[(sha1($item['subject']))][] = $item;
+        }
+        return $array;
     }
 
     /**
@@ -1249,7 +1212,7 @@ trait SolrMarcFincTrait
                             foreach ($linkFields as $current) {
                                 $text = $current->getData();
                                 // Extract parenthetical prefixes:
-                                if (preg_match(self::BSZ_PATTERN, $text, $matches)) {
+                                if (preg_match(self::KXP_PATTERN, $text, $matches)) {
                                     $array[$key]['record_id'] = $matches[2].$matches[3];
                                     if (null != ($sid = $this->getSourceID())) {
                                         $array[$key]['source_id'] = $sid;
@@ -1295,7 +1258,7 @@ trait SolrMarcFincTrait
             foreach ($linkFields as $current) {
                 $text = $current->getData();
                 // Extract parenthetical prefixes:
-                if (preg_match(self::BSZ_PATTERN, $text, $matches)) {
+                if (preg_match(self::KXP_PATTERN, $text, $matches)) {
                     $array[$key]['record_id'] = $matches[2].$matches[3];
                     if (null != ($sid = $this->getSourceID())) {
                         $array[$key]['source_id'] = $sid;
@@ -1516,7 +1479,7 @@ trait SolrMarcFincTrait
                                 foreach ($linkFields as $current) {
                                     $text = $current->getData();
                                     // Extract parenthetical prefixes:
-                                    if (preg_match(self::BSZ_PATTERN, $text, $matches)) {
+                                    if (preg_match(self::KXP_PATTERN, $text, $matches)) {
                                         $array[$i]['record_id']
                                             = $matches[2] . $matches[3];
                                         if (null != ($sid = $this->getSourceID())) {
@@ -1620,7 +1583,7 @@ trait SolrMarcFincTrait
                             foreach ($linkFields as $current) {
                                 $text = $current->getData();
                                 // Extract parenthetical prefixes:
-                                if (preg_match(self::BSZ_PATTERN, $text, $matches)) {
+                                if (preg_match(self::KXP_PATTERN, $text, $matches)) {
                                     $array[$i]['record_id']
                                         = $matches[2] . $matches[3];
                                     if (null != ($sid = $this->getSourceID())) {
diff --git a/themes/finc/templates/RecordDriver/SolrDefault/data-otherRelationshipEntry.phtml b/themes/finc/templates/RecordDriver/SolrDefault/data-otherRelationshipEntry.phtml
index d9a9c6f7714..41bbec84c9e 100644
--- a/themes/finc/templates/RecordDriver/SolrDefault/data-otherRelationshipEntry.phtml
+++ b/themes/finc/templates/RecordDriver/SolrDefault/data-otherRelationshipEntry.phtml
@@ -2,13 +2,13 @@
 <? if (!empty($data)): ?>
     <? foreach ($data as $subject => $values): ?>
         <tr>
-            <th><?=$this->transEsc($subject)?>: </th>
+            <th><?=$this->transEsc($values[0]['subject'])?>: </th>
             <td>
-                <? foreach ($values as $value): ?>
-                    <? if (!empty($value['link']) && $recordLink = $this->RecordLink()->getRecordLink($value['link'], 'record_id')): ?>
-                        <a href="<?=$recordLink?>"><?=$this->escapeHtml($value['text'])?></a>
+                <? foreach ($values as $v): ?>
+                    <? if (isset($v['id'])): ?>
+                        <a href="<?=$this->recordLink()->getUrl($v['id'])?>"><?=$this->escapeHtml($v['text'])?></a>
                     <? else: ?>
-                        <?=$this->escapeHtml($value['text'])?>
+                        <?=$this->escapeHtml($v['text'])?>
                     <? endif; ?>
                     <br/>
                 <? endforeach; ?>
-- 
GitLab