From 3ce24941fcab2d33602882a481a93fb058a43b8f Mon Sep 17 00:00:00 2001
From: Gregor Gawol <gawol@ub.uni-leipzig.de>
Date: Fri, 24 May 2019 13:50:03 +0200
Subject: [PATCH] refs #15234 [fid_bbi] * refactored advanced search view

---
 fid_bbi/config/vufind/facets.ini              |   2 +-
 fid_bbi/languages/de.ini                      |   2 +-
 fid_bbi/languages/en.ini                      |   2 +-
 .../templates/search/advanced/layout.phtml    | 192 ++++++++++++++++++
 .../templates/search/advanced/ranges.phtml    |  76 +++++++
 .../templates/search/advanced/solr.phtml      |  62 ++++++
 6 files changed, 333 insertions(+), 3 deletions(-)
 create mode 100644 themes/fid_bbi/templates/search/advanced/layout.phtml
 create mode 100644 themes/fid_bbi/templates/search/advanced/ranges.phtml
 create mode 100644 themes/fid_bbi/templates/search/advanced/solr.phtml

diff --git a/fid_bbi/config/vufind/facets.ini b/fid_bbi/config/vufind/facets.ini
index de5e3cbe32d..53980785d61 100644
--- a/fid_bbi/config/vufind/facets.ini
+++ b/fid_bbi/config/vufind/facets.ini
@@ -52,9 +52,9 @@ topic_facet = "Related Subjects"
 mega_collection    = Datensammlung
 
 [Advanced]
+facet_avail       = Facet::Availability
 format	  = Medientyp
 mega_collection    = Datensammlung
-facet_avail       = Facet::Availability
 
 [Advanced_Settings]
 facet_limit      = 100
diff --git a/fid_bbi/languages/de.ini b/fid_bbi/languages/de.ini
index 6600e664998..a372c1648b2 100644
--- a/fid_bbi/languages/de.ini
+++ b/fid_bbi/languages/de.ini
@@ -385,7 +385,7 @@ Library = Bibliothek
 LibraryName = Fachinformationsdienst Buch-, Bibliotheks- und Informationswissenschaft (FID BBI)
 LibraryNameShort = Fachinformationsdienst Buch-, Bibliotheks- und Informationswissenschaft
 Library Regulations = Benutzungsordnung
-Limit To = "Begrenze auf"
+Limit To = "Begrenze auf (Mehrfachnennungen mit gedrückter STRG/CTRL-Taste)"
 Link to = "Zur Webseite"
 List of new items = "Neuerwerbungsliste"
 Local Holdings = "Lokale Bestände"
diff --git a/fid_bbi/languages/en.ini b/fid_bbi/languages/en.ini
index 68f5b976641..6b7683d3513 100644
--- a/fid_bbi/languages/en.ini
+++ b/fid_bbi/languages/en.ini
@@ -142,7 +142,7 @@ Library = Library
 LibraryName = Fachinformationsdienst Buch-, Bibliotheks- und Informationswissenschaft (FID BBI)
 LibraryNameShort = Fachinformationsdienst Buch-, Bibliotheks- und Informationswissenschaft
 Library Catalog Username = "Library Catalog User Name"
-Limit To = "Limit to"
+Limit To = "Limit to (Multiple selections with STRG/CTRL-Key)"
 Link to = "To Website"
 List = List
 Loading = Loading
diff --git a/themes/fid_bbi/templates/search/advanced/layout.phtml b/themes/fid_bbi/templates/search/advanced/layout.phtml
new file mode 100644
index 00000000000..8bb57966fe4
--- /dev/null
+++ b/themes/fid_bbi/templates/search/advanced/layout.phtml
@@ -0,0 +1,192 @@
+<!-- fid_bbi: search - advanced - layout -->
+<?php
+// Set page title.
+$this->headTitle($this->translate('Advanced Search'));
+
+// Disable top search box -- this page has a special layout.
+$this->layout()->searchbox = false;
+
+// Set up breadcrumbs:
+$this->layout()->breadcrumbs = '<li>';
+$lastSearchLink = $this->searchMemory()->getLastSearchLink($this->transEsc('Search'));
+$this->layout()->breadcrumbs .= !empty($lastSearchLink)
+  ? $lastSearchLink : $this->transEsc('Search');
+$this->layout()->breadcrumbs .= '</li> <li class="active">' . $this->transEsc('Advanced') . '</li>';
+
+// Set up saved search details:
+if (isset($this->saved) && is_object($this->saved)) {
+  $searchDetails = $this->saved->getParams()->getQuery();
+  if ($searchDetails instanceof \VuFindSearch\Query\Query) {
+    // Not an advanced query -- ignore it.
+    $searchDetails = $groups = false;
+  } else {
+    $groups = $searchDetails->getQueries();
+  }
+  $hasDefaultsApplied = $this->saved->getParams()->hasDefaultsApplied();
+  $searchFilters = $this->saved->getParams()->getFilterList();
+  $hiddenFilters = $this->saved->getParams()->getHiddenFilters();
+} else {
+  $hasDefaultsApplied = $searchDetails = $searchFilters = $groups = false;
+  $hiddenFilters = $this->searchTabs()->getHiddenFilters($this->searchClassId, true);
+}
+
+// Step 1: Load the javascript
+$this->headScript()->appendFile(
+  isset($this->advancedSearchJsOverride) ? $this->advancedSearchJsOverride : 'advanced_search.js'
+);
+// Step 2: Build the page
+$this->headScript()->appendScript(
+  $this->partial(
+    isset($this->buildPageOverride) ? $this->buildPageOverride : 'search/advanced/build_page.phtml',
+    ['options' => $this->options, 'searchDetails' => $searchDetails]
+  )
+);
+
+// Collect previous search queries
+$setSearchGroups = [];
+$setGroupCount = 0;
+$setQueries = [];
+if (isset($searchDetails) && is_object($searchDetails)) {
+  foreach ($searchDetails->getQueries() as $group=>$searchGroup) {
+    $setSearchGroups[$group] = $searchGroup->isNegated() ? 'NOT' : $searchGroup->getOperator();
+    if ($setGroupCount < $group) {
+      $setGroupCount = $group;
+    }
+    if (!isset($setQueries[$group])) {
+      $setQueries[$group] = [];
+    }
+    foreach ($searchGroup->getQueries() as $search) {
+      $setQueries[$group][] = $search;
+    }
+  }
+}
+?>
+
+<?=$this->flashmessages()?>
+<div role="search">
+  <form name="searchForm" id="advSearchForm" method="get" action="<?=$this->url($this->options->getSearchAction())?>">
+    <?php foreach ($hiddenFilters as $key => $filter): ?>
+      <?php foreach ($filter as $value): ?>
+        <input type="hidden" name="hiddenFilters[]" value="<?=$this->escapeHtmlAttr($key) . ':' . $this->escapeHtmlAttr($value)?>" />
+      <?php endforeach; ?>
+    <?php endforeach; ?>
+    <div class="<?=$this->layoutClass('mainbody')?>">
+      <?php $lastSort = $this->searchMemory()->getLastSort($this->searchClassId); ?>
+      <?php if (!empty($lastSort)): ?>
+        <input type="hidden" name="sort" value="<?=$this->escapeHtmlAttr($lastSort)?>" />
+      <?php endif; ?>
+      <div class="clearfix">
+        <h2 class="pull-left flip"><?=$this->transEsc('Advanced Search')?></h2>
+        <div id="groupJoin" class="form-inline pull-right flip">
+          <label for="groupJoinOptions"><?=$this->transEsc("search_match")?>:</label>
+          <select id="groupJoinOptions" name="join" class="form-control">
+            <option value="AND"<?php if($searchDetails && $searchDetails->getOperator()=='ALL'):?> selected<?php endif;?>><?= $this->transEsc('group_AND') ?></option>
+            <option value="OR"<?php if($searchDetails && $searchDetails->getOperator()=='OR'):?> selected<?php endif;?>><?= $this->transEsc('group_OR') ?></option>
+          </select>
+        </div>
+      </div>
+      <?php /* finc: keep icon inside link for consistent functionality */ ?>
+      <span id="groupPlaceHolder" class="hidden">
+      <?php /* fid_bbi: refs #15234 removed btn add search group */?>
+        <?php /*<a href="javascript:void(0);" onClick="addGroup();return false"><i class="fa fa-plus" aria-hidden="true"> </i> <?= $this->transEsc('add_search_group') ?></a>*/?>
+      </span>
+      <?php /* fallback to a fixed set of search groups/fields if JavaScript is turned off */ ?>
+      <div class="no-js">
+        <?php if(!empty($this->formOverride)): ?>
+          <?=$this->formOverride ?>
+        <?php else: ?>
+          <?php for($group=0 ; $group<3 || $group<=$setGroupCount ; $group++): ?>
+            <?php if($group == 0): ?>
+              <div id="new_group_template">
+            <?php endif; ?>
+            <div id="group<?=$group ?>" class="adv-group">
+              <div class="adv-group-terms">
+                <label class="adv-group-label"><?=$this->transEsc("adv_search_label")?>:</label>
+                <?php for($search=0 ; $search<3 || (isset($setQueries[$group]) && $search<count($setQueries[$group])) ; $search++): ?>
+                  <?php if($group == 0 && $search == 0): ?>
+                    <div id="new_search_template">
+                  <?php endif; ?>
+                  <div id="search<?=$group.'_'.$search ?>" class="adv-search">
+                    <input name="lookfor<?=$group ?>[]" id="search_lookfor<?=$group . '_' . $search ?>" class="adv-term-input form-control" type="text"<?php if (isset($setQueries[$group][$search])): ?> value="<?=$this->escapeHtml($setQueries[$group][$search]->getString())?>"<?php endif; ?> aria-label="<?=$this->transEsc("search_terms")?>">
+                    <select class="adv-term-type form-control" name="type<?=$group ?>[]" aria-label="<?=$this->transEsc("Search type")?>">
+                      <?php foreach ($this->options->getAdvancedHandlers() as $searchVal => $searchDesc): ?>
+                        <option value="<?=$this->escapeHtml($searchVal)?>"<?php if(isset($setQueries[$group][$search]) && $searchVal == $setQueries[$group][$search]->getHandler()):?> selected<?php endif;?>><?=$this->transEsc($searchDesc)?></option>
+                      <?php endforeach; ?>
+                    </select>
+                    <a href="javascript:void(0);" class="adv-term-remove hidden">&times;</a>
+                  </div>
+                  <?php if($group == 0 && $search == 0): ?>
+                    </div>
+                    <?php /* finc: moving entire original icon tag inside link WILL BUST removal-button functionality!
+                            (As this will also 'shift search_place_holder') Therefore Keep 'search_place_holder' separate and move icon only !
+                    */ ?>
+                    <span class="float-left">
+                      <span class="search_place_holder hidden" aria-hidden="true"></span>
+                      <a href="javascript:void(0);" class="add_search_link hidden">
+                        <i class="fa fa-plus" aria-hidden="true"></i> <?=$this->transEsc("add_search")?></a>
+                    </span>
+                  <?php endif; ?>
+                <?php endfor; ?>
+              </div>
+              <div class="adv-group-match">
+                <label class="search_bool"><?=$this->transEsc("search_match")?>:&nbsp;</label>
+                <select name="bool<?=$group ?>[]" id="search_bool<?=$group ?>" class="form-control">
+                  <option value="AND"<?php if(isset($setSearchGroups[$group]) && 'AND' == $setSearchGroups[$group]):?> selected<?php endif;?>><?=$this->transEsc("search_AND")?></option>
+                  <option value="OR"<?php if(isset($setSearchGroups[$group]) && 'OR' == $setSearchGroups[$group]):?> selected<?php endif;?>><?=$this->transEsc("search_OR")?></option>
+                  <option value="NOT"<?php if(isset($setSearchGroups[$group]) && 'NOT' == $setSearchGroups[$group]):?> selected<?php endif;?>><?=$this->transEsc("search_NOT")?></option>
+                </select>
+              </div>
+              <a href="javascript:void(0);" class="adv-group-close hidden"><i class="fa fa-close"></i> <?=$this->transEsc("del_search")?></a>
+            </div>
+            <?php if($group == 0): ?>
+              </div>
+            <?php endif; ?>
+          <?php endfor; ?>
+        <?php endif; ?>
+      </div>
+      <?php /* finc: introduce 'fnd-btn'-class to swap submit and clear buttons for consistency */ ?>
+      <div class="adv-submit">
+        <input class="clear-btn btn btn-transparent" type="button" value="<?=$this->transEsc('Clear')?>">
+        <input class="fnd-btn btn btn-primary" type="submit" value="<?= $this->transEsc('Find')?>">
+      </div>
+      <?php if (isset($this->extraAdvancedControls)): ?>
+        <div class="clearfix">
+          <?=$this->extraAdvancedControls ?>
+        </div>
+        <div class="adv-submit margin-t">
+          <input class="clear-btn btn btn-transparent" type="button" value="<?=$this->transEsc('Clear')?>">
+          <input class="fnd-btn btn btn-primary" type="submit" value="<?= $this->transEsc('Find')?>">
+        </div>
+      <?php endif; ?>
+    </div>
+
+    <div class="<?=$this->layoutClass('sidebar')?>">
+      <?php if ($hasDefaultsApplied): ?>
+        <input type="hidden" name="dfApplied" value="1" />
+      <?php endif ?>
+      <?php if (!empty($searchFilters)): ?>
+        <h4><?=$this->transEsc("adv_search_filters")?></h4>
+        <div class="facet-group">
+          <label class="checkbox">
+            <input type="checkbox" checked="checked" class="checkbox-select-all"/>
+            <?=$this->transEsc("adv_search_select_all")?>
+          </label>
+        </div>
+        <?php foreach ($searchFilters as $field => $data): ?>
+          <div class="facet-group">
+            <div class="title"><?=$this->transEsc($field)?></div>
+            <?php foreach ($data as $value): ?>
+              <label class="facet checkbox"><input class="checkbox-select-item" type="checkbox" checked="checked" name="filter[]" value='<?=$this->escapeHtmlAttr($value['field'])?>:"<?=$this->escapeHtmlAttr($value['value'])?>"' /> <?=$this->escapeHtml($value['displayText'])?></label>
+            <?php endforeach; ?>
+          </div>
+        <?php endforeach; ?>
+      <?php endif; ?>
+      <h4><?=$this->transEsc("Search Tips")?></h4>
+      <div class="facet-group">
+        <a class="facet help-link" data-lightbox href="<?=$this->url('help-home')?>?topic=advsearch&amp;_=<?=time() ?>"><?=$this->transEsc("Help with Advanced Search")?></a>
+        <a class="facet help-link" data-lightbox href="<?=$this->url('help-home')?>?topic=search&amp;_=<?=time() ?>"><?=$this->transEsc("Help with Search Operators")?></a>
+      </div>
+    </div>
+  </form>
+</div>
+<!-- fid_bbi: search - advanced - layout - END -->
diff --git a/themes/fid_bbi/templates/search/advanced/ranges.phtml b/themes/fid_bbi/templates/search/advanced/ranges.phtml
new file mode 100644
index 00000000000..ee08fd84a55
--- /dev/null
+++ b/themes/fid_bbi/templates/search/advanced/ranges.phtml
@@ -0,0 +1,76 @@
+<!-- fid_bbi: search - advanced - ranges -->
+<?php if (isset($this->ranges) && !empty($this->ranges)): ?>
+  <?php $params = $this->searchParams($this->searchClassId); $params->activateAllFacets(); ?>
+  <?php foreach ($this->ranges as $current): $escField = $this->escapeHtmlAttr($current['field']); ?>
+    <?php $extraInputAttribs = ($current['type'] == 'date') ? 'maxlength="4" ' : ''; ?>
+    <? /* fid_bbi: refs #15234 move rages to left - GG */ ?>
+    <fieldset class="range left">
+      <legend><?=$this->transEsc($params->getFacetLabel($current['field']))?></legend>
+      <input type="hidden" name="<?=$this->escapeHtmlAttr($current['type'])?>range[]" value="<?=$escField?>"/>
+      <div class="date-fields">
+        <div class="date-from">
+          <label for="<?=$escField?>from"><?=$this->transEsc('date_from')?>:</label>
+          <input type="text" name="<?=$escField?>from" id="<?=$escField?>from" value="<?=isset($current['values'][0])?$this->escapeHtmlAttr($current['values'][0]):''?>" class="form-control" <?=$extraInputAttribs?>/>
+        </div>
+        <div class="date-to">
+          <label for="<?=$escField?>to"><?=$this->transEsc('date_to')?>:</label>
+          <input type="text" name="<?=$escField?>to" id="<?=$escField?>to" value="<?=isset($current['values'][1])?$this->escapeHtmlAttr($current['values'][1]):''?>" class="form-control" <?=$extraInputAttribs?>/>
+        </div>
+      </div>
+      <?php if ($current['type'] == 'date'): ?>
+        <div class="slider-container">
+          <input type="text" id="<?=$escField?><?=$this->escapeHtmlAttr($current['type'])?>Slider">
+        </div>
+        <?php
+          $this->headScript()->appendFile('vendor/bootstrap-slider.min.js');
+          $this->headLink()->appendStylesheet('vendor/bootstrap-slider.min.css');
+          $min = !empty($current['values'][0]) ? min($current['values'][0], 1400) : 1400;
+          $future = date('Y', time() + 31536000);
+          $max = !empty($current['values'][1]) ? max($future, $current['values'][1]) : $future;
+          $low = !empty($current['values'][0]) ? $current['values'][0] : $min;
+          $high = !empty($current['values'][1]) ? $current['values'][1] : $max;
+          $min = intval($min);
+          $max = intval($max);
+          $low = intval($low);
+          $high = intval($high);
+          $init = !empty($current['values'][0]) ? 'fillTexts()' : '';
+          $script = <<<JS
+$(document).ready(function() {
+  var fillTexts = function() {
+    var v = {$escField}dateSlider.getValue();
+    $('#${escField}from').val(v[0]);
+    $('#${escField}to').val(v[1]);
+  };
+  var {$escField}dateSlider = $('#{$escField}dateSlider')
+    .slider({
+       'min':{$min},
+       'max':{$max},
+       'handle':"square",
+       'tooltip':"hide",
+       'value':[{$low},{$high}]
+    })
+    .on('change', fillTexts)
+    .data('slider');
+  {$init}
+});
+
+$('#{$escField}from, #{$escField}to').change(function () {
+  var fromValue = Number($('#{$escField}from').val());
+  var toValue = Number($('#{$escField}to').val());
+  $('#{$escField}dateSlider').slider(
+    'setValue',
+    [
+      isNaN(fromValue) || fromValue <= 0 ? {$min} : fromValue,
+      isNaN(toValue) || toValue <= 0 ? {$max} : toValue
+    ],
+    true
+  );
+});
+JS;
+        ?>
+        <?=$this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $script, 'SET'); ?>
+      <?php endif; ?>
+    </fieldset>
+  <?php endforeach; ?>
+<?php endif; ?>
+<!-- fid_bbi: search - advanced - ranges - END -->
\ No newline at end of file
diff --git a/themes/fid_bbi/templates/search/advanced/solr.phtml b/themes/fid_bbi/templates/search/advanced/solr.phtml
new file mode 100644
index 00000000000..fab87cd8dc3
--- /dev/null
+++ b/themes/fid_bbi/templates/search/advanced/solr.phtml
@@ -0,0 +1,62 @@
+<!-- fid_bbi: search - advanced - solr -->
+<?php if (!empty($this->facetList) || !empty($this->checkboxFacets)): ?>
+  <fieldset class="solr-facets">
+    <legend><?=$this->transEsc('Limit To')?></legend>
+    <?php if (!empty($this->checkboxFacets)): ?>
+      <?=$this->render('search/advanced/checkbox-filters.phtml')?>
+    <?php endif; ?>
+    <?php /* finc: we need the limiter-boxes class to set select height to auto + remove bg image - CK */ ?>
+    <div class="solr-facet-container limiter-boxes">
+      <?php //finc: narrow the facet list via whitespace from config, #13783, DM
+         $this->facetList = $this->sideFacet()->displayAllowedFacetValues($this->facetList); ?>
+      <?php foreach ($this->facetList as $field => $list): ?>
+        <div class="solr-adv-facet">
+          <label for="limit_<?=$this->escapeHtmlAttr(str_replace(' ', '', $field))?>"><?=$this->transEsc($list['label'])?>:</label>
+          <select class="form-control" id="limit_<?=$this->escapeHtmlAttr(str_replace(' ', '', $field))?>" name="filter[]" multiple="multiple" size="10">
+            <?php if (is_array($this->hierarchicalFacets) && in_array($field, $this->hierarchicalFacets)): ?>
+              <?php foreach ($list['list'] as $value): ?>
+                <?php $display = str_pad('', 4 * $value['level'] * 6, '&nbsp;', STR_PAD_LEFT) . $this->escapeHtml($value['displayText']); ?>
+                <option
+                  value="<?=$this->escapeHtmlAttr(($value['operator'] == 'OR' ? '~' : '') . $field . ':"' . $value['value'] . '"')?>"<?=(isset($value['selected']) && $value['selected']) ? ' selected="selected"' : ''?>><?=$display?></option>
+              <?php endforeach; ?>
+            <?php else: ?>
+              <?php
+              // Sort the current facet list alphabetically; we'll use this data
+              // along with the foreach below to display facet options in the
+              // correct order.
+              $sorted = [];
+              foreach ($list['list'] as $i => $value) {
+                if (!empty($value['displayText'])) {
+                  $sorted[$i] = $value['displayText'];
+                }
+              }
+              natcasesort($sorted);
+              ?>
+              <?php foreach ($sorted as $i => $display): ?>
+                <?php $value = $list['list'][$i]; ?>
+                <option
+                  value="<?=$this->escapeHtmlAttr(($value['operator'] == 'OR' ? '~' : '') . $field . ':"' . $value['value'] . '"')?>"<?=(isset($value['selected']) && $value['selected']) ? ' selected="selected"' : ''?>><?=$this->escapeHtml($display)?></option>
+              <?php endforeach; ?>
+            <?php endif; ?>
+          </select>
+        </div>
+      <?php endforeach; ?>
+    </div>
+  </fieldset>
+
+<?php endif; ?>
+
+<?php if (isset($this->illustratedLimit)): ?>
+  <fieldset class="solr">
+    <legend><?=$this->transEsc("Illustrated")?>:</legend>
+    <?php foreach ($this->illustratedLimit as $current): ?>
+      <input id="illustrated_<?=$this->escapeHtmlAttr($current['value'])?>" type="radio" name="illustration"
+             value="<?=$this->escapeHtmlAttr($current['value'])?>"<?=$current['selected'] ? ' checked="checked"' : ''?>/>
+      <label for="illustrated_<?=$this->escapeHtmlAttr($current['value'])?>"><?=$this->transEsc($current['text'])?></label><br/>
+    <?php endforeach; ?>
+  </fieldset>
+<?php endif; ?>
+<?php /*fid_bbi: refs #15234 removed limit - GG */ ?>
+<?/*=$this->render('search/advanced/limit.phtml')*/?>
+<?=$this->render('search/advanced/ranges.phtml')?>
+<!-- fid_bbi: search - advanced - solr - END -->
-- 
GitLab