From fb9455847bd105962548ff3a05e2443a746efa70 Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Thu, 11 Jun 2020 14:12:44 -0400
Subject: [PATCH] Remove Amazon content functionality. (#1642)

- Resolves VUFIND-1284.
---
 composer.json                                 |    2 -
 composer.lock                                 |  487 +++--
 config/vufind/config.ini                      |   21 +-
 module/VuFind/src/VuFind/Config/Upgrade.php   |   24 +-
 .../src/VuFind/Content/AbstractAmazon.php     |   88 -
 .../VuFind/Content/AbstractAmazonFactory.php  |   75 -
 .../src/VuFind/Content/Covers/Amazon.php      |  148 --
 .../VuFind/Content/Covers/AmazonFactory.php   |   71 -
 .../VuFind/Content/Covers/PluginManager.php   |    3 +-
 .../src/VuFind/Content/Reviews/Amazon.php     |  137 --
 .../Content/Reviews/AmazonEditorial.php       |   94 -
 .../VuFind/Content/Reviews/PluginManager.php  |    6 +-
 .../fixtures/configs/amazoncover/config.ini   | 1896 +++++++++++++++++
 .../fixtures/configs/amazonreview/config.ini  | 1896 +++++++++++++++++
 .../tests/fixtures/content/amazon-cover       |  Bin 1530 -> 0 bytes
 .../src/VuFindTest/Config/UpgradeTest.php     |   38 +
 .../VuFindTest/Content/Covers/AmazonTest.php  |  175 --
 17 files changed, 4173 insertions(+), 988 deletions(-)
 delete mode 100644 module/VuFind/src/VuFind/Content/AbstractAmazon.php
 delete mode 100644 module/VuFind/src/VuFind/Content/AbstractAmazonFactory.php
 delete mode 100644 module/VuFind/src/VuFind/Content/Covers/Amazon.php
 delete mode 100644 module/VuFind/src/VuFind/Content/Covers/AmazonFactory.php
 delete mode 100644 module/VuFind/src/VuFind/Content/Reviews/Amazon.php
 delete mode 100644 module/VuFind/src/VuFind/Content/Reviews/AmazonEditorial.php
 create mode 100644 module/VuFind/tests/fixtures/configs/amazoncover/config.ini
 create mode 100644 module/VuFind/tests/fixtures/configs/amazonreview/config.ini
 delete mode 100644 module/VuFind/tests/fixtures/content/amazon-cover
 delete mode 100644 module/VuFind/tests/unit-tests/src/VuFindTest/Content/Covers/AmazonTest.php

diff --git a/composer.json b/composer.json
index 397f4015abf..6fa56730466 100644
--- a/composer.json
+++ b/composer.json
@@ -74,8 +74,6 @@
         "wikimedia/composer-merge-plugin": "1.4.1",
         "wikimedia/less.php": "2.0.0",
         "yajra/laravel-pdo-via-oci8": "2.1.1",
-        "zendframework/zendrest": "2.0.2",
-        "zendframework/zendservice-amazon": "2.3.1",
         "zf-commons/zfc-rbac": "2.6.3"
     },
     "require-dev": {
diff --git a/composer.lock b/composer.lock
index ea72f6b0786..7352a1fd4d3 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "c6eb7e793cc11fdaff97a3b528564f60",
+    "content-hash": "8480041cf492ad993f8a269095244141",
     "packages": [
         {
             "name": "ahand/mobileesp",
@@ -979,6 +979,12 @@
                 "BSD-3-Clause"
             ],
             "description": "Replace zendframework and zfcampus packages with their Laminas Project equivalents.",
+            "funding": [
+                {
+                    "url": "https://funding.communitybridge.org/projects/laminas-project",
+                    "type": "community_bridge"
+                }
+            ],
             "time": "2020-05-20T13:45:39+00:00"
         },
         {
@@ -3061,56 +3067,6 @@
             ],
             "time": "2019-12-31T18:03:19+00:00"
         },
-        {
-            "name": "laminas/laminas-xml",
-            "version": "1.2.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/laminas/laminas-xml.git",
-                "reference": "879cc66d1bba6a37705e98074f52a6960c220020"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/laminas/laminas-xml/zipball/879cc66d1bba6a37705e98074f52a6960c220020",
-                "reference": "879cc66d1bba6a37705e98074f52a6960c220020",
-                "shasum": ""
-            },
-            "require": {
-                "laminas/laminas-zendframework-bridge": "^1.0",
-                "php": "^5.6 || ^7.0"
-            },
-            "replace": {
-                "zendframework/zendxml": "self.version"
-            },
-            "require-dev": {
-                "laminas/laminas-coding-standard": "~1.0.0",
-                "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.4"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.2.x-dev",
-                    "dev-develop": "1.3.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Laminas\\Xml\\": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "description": "Utility library for XML usage, best practices, and security in PHP",
-            "homepage": "https://laminas.dev",
-            "keywords": [
-                "laminas",
-                "security",
-                "xml"
-            ],
-            "time": "2019-12-31T18:05:42+00:00"
-        },
         {
             "name": "laminas/laminas-zendframework-bridge",
             "version": "1.0.4",
@@ -3161,6 +3117,12 @@
                 "laminas",
                 "zf"
             ],
+            "funding": [
+                {
+                    "url": "https://funding.communitybridge.org/projects/laminas-project",
+                    "type": "community_bridge"
+                }
+            ],
             "time": "2020-05-20T16:45:56+00:00"
         },
         {
@@ -3235,6 +3197,32 @@
                 "md",
                 "parser"
             ],
+            "funding": [
+                {
+                    "url": "https://enjoy.gitstore.app/repositories/thephpleague/commonmark",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://www.colinodell.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://www.paypal.me/colinpodell/10.00",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/colinodell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://www.patreon.com/colinodell",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/league/commonmark",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-04T22:15:21+00:00"
         },
         {
@@ -4720,6 +4708,20 @@
                 "symfony",
                 "words"
             ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-20T08:37:50+00:00"
         },
         {
@@ -4774,6 +4776,20 @@
                 "configuration",
                 "options"
             ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-23T12:09:32+00:00"
         },
         {
@@ -4832,6 +4848,20 @@
                 "polyfill",
                 "portable"
             ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-12T16:14:59+00:00"
         },
         {
@@ -4891,6 +4921,20 @@
                 "portable",
                 "shim"
             ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-12T16:47:27+00:00"
         },
         {
@@ -4949,6 +4993,20 @@
                 "portable",
                 "shim"
             ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-12T16:47:27+00:00"
         },
         {
@@ -5016,6 +5074,20 @@
                 "property path",
                 "reflection"
             ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-30T18:50:54+00:00"
         },
         {
@@ -5531,104 +5603,6 @@
             "description": "PDO userspace driver proxying calls to PHP OCI8 driver",
             "time": "2019-12-05T06:00:56+00:00"
         },
-        {
-            "name": "zendframework/zendrest",
-            "version": "2.0.2",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/zendframework/ZendRest.git",
-                "reference": "7427d242b4546e5aef1206d2c97e402109d8843e"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/zendframework/ZendRest/zipball/7427d242b4546e5aef1206d2c97e402109d8843e",
-                "reference": "7427d242b4546e5aef1206d2c97e402109d8843e",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3",
-                "zendframework/zend-http": "~2.0",
-                "zendframework/zend-uri": "~2.0",
-                "zendframework/zendxml": "~1.0-dev"
-            },
-            "type": "library",
-            "autoload": {
-                "psr-0": {
-                    "ZendRest": "library/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "homepage": "http://packages.zendframework.com/",
-            "keywords": [
-                "rest",
-                "zf2"
-            ],
-            "abandoned": true,
-            "time": "2014-03-05T22:32:09+00:00"
-        },
-        {
-            "name": "zendframework/zendservice-amazon",
-            "version": "2.3.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/zendframework/ZendService_Amazon.git",
-                "reference": "0bb035f5b5fe88e443d8dcd96a8415fea2729508"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/zendframework/ZendService_Amazon/zipball/0bb035f5b5fe88e443d8dcd96a8415fea2729508",
-                "reference": "0bb035f5b5fe88e443d8dcd96a8415fea2729508",
-                "shasum": ""
-            },
-            "require": {
-                "php": "^5.6 || ^7.0",
-                "zendframework/zend-crypt": "^2.6 || ^3.2",
-                "zendframework/zend-http": "^2.6",
-                "zendframework/zend-json": "^2.6 || ^3.0",
-                "zendframework/zendrest": "~2.0",
-                "zendframework/zendxml": "^1.0"
-            },
-            "require-dev": {
-                "malukenho/docheader": "^0.1.5",
-                "phpunit/phpunit": "^6.0.8 || ^5.7.15",
-                "zendframework/zend-coding-standard": "~1.0.0",
-                "zendframework/zend-i18n": "~2.0"
-            },
-            "suggest": {
-                "zendframework/zend-uri": "Zend\\Uri component"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "2.3.x-dev",
-                    "dev-develop": "2.4.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "ZendService\\Amazon\\": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "description": "OOP wrapper for the Amazon web service",
-            "homepage": "http://packages.zendframework.com/",
-            "keywords": [
-                "amazon",
-                "ec2",
-                "s3",
-                "simpledb",
-                "sqs",
-                "zf2"
-            ],
-            "abandoned": "aws/aws-sdk-php",
-            "time": "2019-02-07T18:15:54+00:00"
-        },
         {
             "name": "zf-commons/zfc-rbac",
             "version": "v2.6.3",
@@ -5946,16 +5920,16 @@
         },
         {
             "name": "composer/xdebug-handler",
-            "version": "1.4.1",
+            "version": "1.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/composer/xdebug-handler.git",
-                "reference": "1ab9842d69e64fb3a01be6b656501032d1b78cb7"
+                "reference": "fa2aaf99e2087f013a14f7432c1cd2dd7d8f1f51"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/1ab9842d69e64fb3a01be6b656501032d1b78cb7",
-                "reference": "1ab9842d69e64fb3a01be6b656501032d1b78cb7",
+                "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/fa2aaf99e2087f013a14f7432c1cd2dd7d8f1f51",
+                "reference": "fa2aaf99e2087f013a14f7432c1cd2dd7d8f1f51",
                 "shasum": ""
             },
             "require": {
@@ -5986,7 +5960,21 @@
                 "Xdebug",
                 "performance"
             ],
-            "time": "2020-03-01T12:26:26+00:00"
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-06-04T11:16:35+00:00"
         },
         {
             "name": "dmore/chrome-mink-driver",
@@ -6159,6 +6147,20 @@
                 "constructor",
                 "instantiate"
             ],
+            "funding": [
+                {
+                    "url": "https://www.doctrine-project.org/sponsorship.html",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://www.patreon.com/phpdoctrine",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-29T17:27:14+00:00"
         },
         {
@@ -6221,6 +6223,20 @@
                 "parser",
                 "php"
             ],
+            "funding": [
+                {
+                    "url": "https://www.doctrine-project.org/sponsorship.html",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://www.patreon.com/phpdoctrine",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-25T17:44:05+00:00"
         },
         {
@@ -7282,6 +7298,16 @@
                 "testing",
                 "xunit"
             ],
+            "funding": [
+                {
+                    "url": "https://phpunit.de/donate.html",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
             "time": "2020-04-23T04:39:42+00:00"
         },
         {
@@ -8106,6 +8132,20 @@
             ],
             "description": "Symfony Config Component",
             "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-23T09:11:46+00:00"
         },
         {
@@ -8159,6 +8199,20 @@
             ],
             "description": "Symfony CssSelector Component",
             "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-03-16T08:31:04+00:00"
         },
         {
@@ -8232,6 +8286,20 @@
             ],
             "description": "Symfony DependencyInjection Component",
             "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-30T20:06:45+00:00"
         },
         {
@@ -8302,6 +8370,20 @@
             ],
             "description": "Symfony EventDispatcher Component",
             "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-20T08:37:50+00:00"
         },
         {
@@ -8410,6 +8492,20 @@
             ],
             "description": "Symfony Filesystem Component",
             "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-30T18:50:54+00:00"
         },
         {
@@ -8459,6 +8555,20 @@
             ],
             "description": "Symfony Finder Component",
             "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-03-27T16:54:36+00:00"
         },
         {
@@ -8518,6 +8628,20 @@
                 "portable",
                 "shim"
             ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-12T16:47:27+00:00"
         },
         {
@@ -8573,6 +8697,20 @@
                 "portable",
                 "shim"
             ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-12T16:47:27+00:00"
         },
         {
@@ -8622,6 +8760,20 @@
             ],
             "description": "Symfony Process Component",
             "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-30T20:06:45+00:00"
         },
         {
@@ -8672,20 +8824,34 @@
             ],
             "description": "Symfony Stopwatch Component",
             "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
             "time": "2020-05-20T08:37:50+00:00"
         },
         {
             "name": "textalk/websocket",
-            "version": "1.3.0",
+            "version": "1.3.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Textalk/websocket-php.git",
-                "reference": "9fbb3b4ebaeb823c97270b409431b0d85617e5a7"
+                "reference": "fe348408a43cc646d08a3ae73e7877370441c7ee"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/9fbb3b4ebaeb823c97270b409431b0d85617e5a7",
-                "reference": "9fbb3b4ebaeb823c97270b409431b0d85617e5a7",
+                "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/fe348408a43cc646d08a3ae73e7877370441c7ee",
+                "reference": "fe348408a43cc646d08a3ae73e7877370441c7ee",
                 "shasum": ""
             },
             "require": {
@@ -8717,7 +8883,7 @@
                 }
             ],
             "description": "WebSocket client and server",
-            "time": "2020-05-31T08:15:03+00:00"
+            "time": "2020-06-07T12:11:38+00:00"
         },
         {
             "name": "theseer/fdomdocument",
@@ -8862,5 +9028,6 @@
     "platform-dev": [],
     "platform-overrides": {
         "php": "7.2"
-    }
+    },
+    "plugin-api-version": "1.1.0"
 }
diff --git a/config/vufind/config.ini b/config/vufind/config.ini
index 94b801297bb..a5039f1e594 100644
--- a/config/vufind/config.ini
+++ b/config/vufind/config.ini
@@ -778,9 +778,6 @@ database          = mysql://root@localhost/vufind
 ; External Content is Optional.
 ; To use multiple, separate with a comma.  Priority will be given by the order listed
 ; Account id is separated with a colon, if no id is used then no colon is necessary
-; For Amazon, use your 20-character access key in the coverimages and reviews values;
-; you must also provide your 40-character secret key in the amazonsecret value and
-; your associate ID in the amazonassociate value.
 ;
 ; IMPORTANT: Review content providers' terms of service before turning them on.
 ;            Terms may change, and not all content sources are appropriate for all
@@ -807,7 +804,7 @@ database          = mysql://root@localhost/vufind
 ; coversize setting to false:
 ;coversize = false
 
-; You can select Syndetics, LibraryThing, Summon, Amazon, Booksite, OpenLibrary,
+; You can select Syndetics, LibraryThing, Summon, Booksite, OpenLibrary,
 ; Contentcafe, Buchhandel.de, Google Books, BrowZine and/or LocalFile.
 ;   Note: BrowZine requires you to have BrowZine.ini configured appropriately.
 ;   Note: Summon service takes a Serials Solutions client key, NOT Summon API key!
@@ -828,7 +825,7 @@ database          = mysql://root@localhost/vufind
 ;          %vufind-home%      - The VUFIND_HOME environment variable
 ;          %vufind-local-dir% - The VUFIND_LOCAL_DIR environment variable
 ;        Example: LocalFile:%vufind-local-dir%/path/to/file/%size%/issn/%issn%.%anyimage%
-;coverimages     = Syndetics:MySyndeticsId,Amazon:MyAccessKeyId,Booksite,LibraryThing:MyLibraryThingId,Google,OpenLibrary,Summon:MySerialsSolutionsClientKey,Contentcafe:MyContentCafeID,BrowZine,LocalFile:PathToFile
+;coverimages     = Syndetics:MySyndeticsId,Booksite,LibraryThing:MyLibraryThingId,Google,OpenLibrary,Summon:MySerialsSolutionsClientKey,Contentcafe:MyContentCafeID,BrowZine,LocalFile:PathToFile
 
 ; This setting controls which services will have images cached on your local disk.
 ; Set to true to cache all applicable services. Set to false to disable caching. Set
@@ -855,13 +852,12 @@ coverimagesCache = true
 ; path relative to the base of your theme directory for a static image to display.
 noCoverAvailableImage = images/noCover2.gif
 
-; You can select from Syndetics, SyndeticsPlus, Amazon Editorial, Amazon, Booksite
-; and/or the Guardian
+; You can select from Syndetics, SyndeticsPlus, Booksite and/or the Guardian
 ;   Note: If the API key is omitted, e.g. "Guardian:", only the review title, byline,
 ;         Guardian logo and a link to the full Guardian page will be displayed
 ;   Note: The Guardian API changed in 2014; if you signed up before that date, you
 ;         may need to obtain a new API key for continued access.
-;reviews         = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsID,AmazonEditorial:MyAccessKeyId,Amazon:MyAccessKeyId,Booksite,Guardian:MyGuardianKeyId
+;reviews         = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsID,Booksite,Guardian:MyGuardianKeyId
 
 ; You can select from Syndetics or SyndeticsPlus
 ;excerpts        = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsId
@@ -892,15 +888,6 @@ noCoverAvailableImage = images/noCover2.gif
 ; heap size settings.  For details, see: https://vufind.org/jira/browse/VUFIND-630
 authors         = Wikipedia
 
-; You can look up your secret key by logging into http://aws.amazon.com and clicking
-; "Access Identifiers" under "Your Account".
-;amazonsecret    = MyAmazonSecretKey
-
-; You can sign up for an associate ID by logging into
-; https://affiliate-program.amazon.com .  Please make sure your instance of VuFind
-; complies with Amazon's agreements before enabling this feature.
-;amazonassociate = MyAmazonAssociateID
-
 ; You can select from Google, OpenLibrary, HathiTrust.  You should consult
 ; https://developers.google.com/books/branding before using Google Book Search.
 ;previews       = Google,OpenLibrary,HathiTrust
diff --git a/module/VuFind/src/VuFind/Config/Upgrade.php b/module/VuFind/src/VuFind/Config/Upgrade.php
index 294337ac54b..58faf74a396 100644
--- a/module/VuFind/src/VuFind/Config/Upgrade.php
+++ b/module/VuFind/src/VuFind/Config/Upgrade.php
@@ -505,25 +505,13 @@ class Upgrade
     {
         // Warn the user if they have Amazon enabled but do not have the appropriate
         // credentials set up.
-        $hasAmazonReview = isset($config['Content']['reviews'])
-            && stristr($config['Content']['reviews'], 'amazon');
-        $hasAmazonCover = isset($config['Content']['coverimages'])
-            && stristr($config['Content']['coverimages'], 'amazon');
+        $hasAmazonReview = stristr($config['Content']['reviews'] ?? '', 'amazon');
+        $hasAmazonCover = stristr($config['Content']['coverimages'] ?? '', 'amazon');
         if ($hasAmazonReview || $hasAmazonCover) {
-            if (!isset($config['Content']['amazonsecret'])) {
-                $this->addWarning(
-                    'WARNING: You have Amazon content enabled but are missing '
-                    . 'the required amazonsecret setting in the [Content] section '
-                    . 'of config.ini'
-                );
-            }
-            if (!isset($config['Content']['amazonassociate'])) {
-                $this->addWarning(
-                    'WARNING: You have Amazon content enabled but are missing '
-                    . 'the required amazonassociate setting in the [Content] section'
-                    . ' of config.ini'
-                );
-            }
+            $this->addWarning(
+                'WARNING: You have Amazon content enabled, but VuFind no longer '
+                . 'supports it. You should remove Amazon references from config.ini.'
+            );
         }
     }
 
diff --git a/module/VuFind/src/VuFind/Content/AbstractAmazon.php b/module/VuFind/src/VuFind/Content/AbstractAmazon.php
deleted file mode 100644
index 25d02f0a19f..00000000000
--- a/module/VuFind/src/VuFind/Content/AbstractAmazon.php
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-/**
- * Generic Amazon content loader.
- *
- * PHP version 7
- *
- * Copyright (C) Villanova University 2010.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * @category VuFind
- * @package  Content
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-namespace VuFind\Content;
-
-/**
- * Generic Amazon content loader.
- *
- * @category VuFind
- * @package  Content
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-abstract class AbstractAmazon extends AbstractBase
-{
-    /**
-     * Associate ID
-     *
-     * @var string
-     */
-    protected $associate;
-
-    /**
-     * Secret key
-     *
-     * @var string
-     */
-    protected $secret;
-
-    /**
-     * "Supplied by Amazon" label, appropriately translated
-     *
-     * @var string
-     */
-    protected $label;
-
-    /**
-     * Constructor
-     *
-     * @param string $associate Associate ID
-     * @param string $secret    Secret key
-     * @param string $label     "Supplied by Amazon" label, appropriately translated
-     */
-    public function __construct($associate, $secret, $label)
-    {
-        $this->associate = $associate;
-        $this->secret = $secret;
-        $this->label = $label;
-    }
-
-    /**
-     * Get copyright message
-     *
-     * @param string $isbn ISBN to use for linking
-     *
-     * @return string
-     */
-    protected function getCopyright($isbn)
-    {
-        return '<div><a target="new" href="http://amazon.com/dp/'
-            . $isbn . '">' . htmlspecialchars($this->label) . '</a></div>';
-    }
-}
diff --git a/module/VuFind/src/VuFind/Content/AbstractAmazonFactory.php b/module/VuFind/src/VuFind/Content/AbstractAmazonFactory.php
deleted file mode 100644
index 4c595dbcc31..00000000000
--- a/module/VuFind/src/VuFind/Content/AbstractAmazonFactory.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-/**
- * Generic Amazon content plugin factory.
- *
- * PHP version 7
- *
- * Copyright (C) Villanova University 2018.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * @category VuFind
- * @package  Content
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-namespace VuFind\Content;
-
-use Interop\Container\ContainerInterface;
-
-/**
- * Generic Amazon content plugin factory.
- *
- * @category VuFind
- * @package  Content
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-class AbstractAmazonFactory
-    implements \Laminas\ServiceManager\Factory\FactoryInterface
-{
-    /**
-     * Create an object
-     *
-     * @param ContainerInterface $container     Service manager
-     * @param string             $requestedName Service being created
-     * @param null|array         $options       Extra options (optional)
-     *
-     * @return object
-     *
-     * @throws ServiceNotFoundException if unable to resolve the service.
-     * @throws ServiceNotCreatedException if an exception is raised when
-     * creating a service.
-     * @throws ContainerException if any other error occurs
-     */
-    public function __invoke(ContainerInterface $container, $requestedName,
-        array $options = null
-    ) {
-        if ($options !== null) {
-            throw new \Exception('Unexpected options sent to factory!');
-        }
-        $config = $container->get(\VuFind\Config\PluginManager::class)
-            ->get('config');
-        $associate = isset($config->Content->amazonassociate)
-            ? $config->Content->amazonassociate : null;
-        $secret = isset($config->Content->amazonsecret)
-            ? $config->Content->amazonsecret : null;
-        $label = $container->get(\Laminas\Mvc\I18n\Translator::class)->translate(
-            'Supplied by Amazon'
-        );
-        return new $requestedName($associate, $secret, $label);
-    }
-}
diff --git a/module/VuFind/src/VuFind/Content/Covers/Amazon.php b/module/VuFind/src/VuFind/Content/Covers/Amazon.php
deleted file mode 100644
index 2ba71c6e663..00000000000
--- a/module/VuFind/src/VuFind/Content/Covers/Amazon.php
+++ /dev/null
@@ -1,148 +0,0 @@
-<?php
-/**
- * Amazon cover content loader.
- *
- * PHP version 7
- *
- * Copyright (C) Villanova University 2010.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * @category VuFind
- * @package  Content
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-namespace VuFind\Content\Covers;
-
-use ZendService\Amazon\Amazon as AmazonService;
-
-/**
- * Amazon cover content loader.
- *
- * @category VuFind
- * @package  Content
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-class Amazon extends \VuFind\Content\AbstractCover
-    implements \VuFindHttp\HttpServiceAwareInterface
-{
-    use \VuFindHttp\HttpServiceAwareTrait;
-
-    /**
-     * Associate ID
-     *
-     * @var string
-     */
-    protected $associate;
-
-    /**
-     * Secret key
-     *
-     * @var string
-     */
-    protected $secret;
-
-    /**
-     * Constructor
-     *
-     * @param string $associate Associate ID
-     * @param string $secret    Secret key
-     */
-    public function __construct($associate, $secret)
-    {
-        $this->associate = $associate;
-        $this->secret = $secret;
-        $this->supportsIsbn = true;
-    }
-
-    /**
-     * Get an HTTP client
-     *
-     * @param string $url URL for client to use
-     *
-     * @return \Laminas\Http\Client
-     */
-    protected function getHttpClient($url = null)
-    {
-        if (null === $this->httpService) {
-            throw new \Exception('HTTP service missing.');
-        }
-        return $this->httpService->createClient($url);
-    }
-
-    /**
-     * Get image URL for a particular API key and set of IDs (or false if invalid).
-     *
-     * @param string $key  API key
-     * @param string $size Size of image to load (small/medium/large)
-     * @param array  $ids  Associative array of identifiers (keys may include 'isbn'
-     * pointing to an ISBN object and 'issn' pointing to a string)
-     *
-     * @return string|bool
-     */
-    public function getUrl($key, $size, $ids)
-    {
-        try {
-            $params = [
-                'ResponseGroup' => 'Images', 'AssociateTag' => $this->associate
-            ];
-            // TODO: add support for 13-digit ISBNs (requires extra lookup)
-            $isbn = isset($ids['isbn']) ? $ids['isbn']->get10() : false;
-            if (!$isbn) {
-                return false;
-            }
-            $result = $this->getAmazonService($key)->itemLookup($isbn, $params);
-        } catch (\Exception $e) {
-            // Something went wrong?  Just report failure:
-            return false;
-        }
-
-        // Where in the response can we find the URL we need?
-        switch ($size) {
-        case 'small':
-        case 'medium':
-        case 'large':
-            $imageIndex = ucwords($size) . 'Image';
-            break;
-        default:
-            $imageIndex = false;
-            break;
-        }
-
-        if ($imageIndex && isset($result->$imageIndex->Url)) {
-            $imageUrl = (string)$result->$imageIndex->Url;
-            return $imageUrl;
-        }
-
-        return false;
-    }
-
-    /**
-     * Get an AmazonService object for the specified key.
-     *
-     * @param string $key API key
-     *
-     * @return AmazonService
-     */
-    protected function getAmazonService($key)
-    {
-        $service = new AmazonService($key, 'US', $this->secret);
-        $service->getRestClient()->setHttpClient($this->getHttpClient());
-        return $service;
-    }
-}
diff --git a/module/VuFind/src/VuFind/Content/Covers/AmazonFactory.php b/module/VuFind/src/VuFind/Content/Covers/AmazonFactory.php
deleted file mode 100644
index f2243074a7e..00000000000
--- a/module/VuFind/src/VuFind/Content/Covers/AmazonFactory.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-/**
- * Amazon cover loader factory
- *
- * PHP version 7
- *
- * Copyright (C) Villanova University 2019.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * @category VuFind
- * @package  Content
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development:plugins:record_drivers Wiki
- */
-namespace VuFind\Content\Covers;
-
-use Interop\Container\ContainerInterface;
-
-/**
- * Amazon cover loader factory
- *
- * @category VuFind
- * @package  Content
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development:plugins:record_drivers Wiki
- */
-class AmazonFactory implements \Laminas\ServiceManager\Factory\FactoryInterface
-{
-    /**
-     * Create an object
-     *
-     * @param ContainerInterface $container     Service manager
-     * @param string             $requestedName Service being created
-     * @param null|array         $options       Extra options (optional)
-     *
-     * @return object
-     *
-     * @throws ServiceNotFoundException if unable to resolve the service.
-     * @throws ServiceNotCreatedException if an exception is raised when
-     * creating a service.
-     * @throws ContainerException if any other error occurs
-     *
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-     */
-    public function __invoke(ContainerInterface $container, $requestedName,
-        array $options = null
-    ) {
-        if (!empty($options)) {
-            throw new \Exception('Unexpected options passed to factory.');
-        }
-        $config = $container->get(\VuFind\Config\PluginManager::class)
-            ->get('config');
-        $associate = $config->Content->amazonassociate ?? null;
-        $secret = $config->Content->amazonsecret ?? null;
-        return new $requestedName($associate, $secret);
-    }
-}
diff --git a/module/VuFind/src/VuFind/Content/Covers/PluginManager.php b/module/VuFind/src/VuFind/Content/Covers/PluginManager.php
index f260e3a13d4..9bd9b88913d 100644
--- a/module/VuFind/src/VuFind/Content/Covers/PluginManager.php
+++ b/module/VuFind/src/VuFind/Content/Covers/PluginManager.php
@@ -46,7 +46,8 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager
      * @var array
      */
     protected $aliases = [
-        'amazon' => Amazon::class,
+        Amazon::class => Deprecated::class,
+        'amazon' => Deprecated::class,
         'booksite' => Booksite::class,
         'buchhandel' => Buchhandel::class,
         'browzine' => BrowZine::class,
diff --git a/module/VuFind/src/VuFind/Content/Reviews/Amazon.php b/module/VuFind/src/VuFind/Content/Reviews/Amazon.php
deleted file mode 100644
index fc73673bbeb..00000000000
--- a/module/VuFind/src/VuFind/Content/Reviews/Amazon.php
+++ /dev/null
@@ -1,137 +0,0 @@
-<?php
-/**
- * Amazon review content loader.
- *
- * PHP version 7
- *
- * Copyright (C) Villanova University 2010.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * @category VuFind
- * @package  Content
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-namespace VuFind\Content\Reviews;
-
-/**
- * Amazon review content loader.
- *
- * @category VuFind
- * @package  Content
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-class Amazon extends \VuFind\Content\AbstractAmazon
-{
-    /**
-     * Amazon Reviews
-     *
-     * This method is responsible for connecting to Amazon AWS and abstracting
-     * customer reviews for the specific ISBN
-     *
-     * @param string           $key     API key
-     * @param \VuFindCode\ISBN $isbnObj ISBN object
-     *
-     * @throws \Exception
-     * @return array     Returns array with review data.
-     * @author Andrew Nagy <vufind-tech@lists.sourceforge.net>
-     */
-    public function loadByIsbn($key, \VuFindCode\ISBN $isbnObj)
-    {
-        // TODO: rewrite this to use ZendService\Amazon.
-
-        // Collect all the parameters:
-        $endpoint = 'webservices.amazon.com';
-        $requestURI = '/onca/xml';
-        $isbn = $this->getIsbn10($isbnObj);
-        $params = [
-            'AWSAccessKeyId' => $key,
-            'ItemId' => $isbn,
-            'Service' => 'AWSECommerceService',
-            'Operation' => 'ItemLookup',
-            'ResponseGroup' => 'Reviews',
-            'Version' => '2010-10-10',
-            'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
-            'AssociateTag' => $this->associate
-        ];
-
-        // Alphabetize the parameters:
-        ksort($params);
-
-        // URL encode and assemble the parameters:
-        $encodedParams = [];
-        foreach ($params as $key => $value) {
-            $encodedParams[] = rawurlencode($key) . '=' . rawurlencode($value);
-        }
-        $encodedParams = implode('&', $encodedParams);
-
-        // Build the HMAC signature:
-        $sigData = "GET\n{$endpoint}\n{$requestURI}\n{$encodedParams}";
-        $hmacHash = hash_hmac('sha256', $sigData, $this->secret, 1);
-
-        // Save the final request URL:
-        $url = 'http://' . $endpoint . $requestURI . '?' . $encodedParams
-            . '&Signature=' . rawurlencode(base64_encode($hmacHash));
-
-        $result = $this->getHttpClient($url)->send();
-
-        $data = !$result->isSuccess()
-            ? false : simplexml_load_string($result->getBody());
-        if (!$data) {
-            return [];
-        }
-
-        $result = [];
-        $reviews = isset($data->Items->Item->CustomerReviews->Review)
-            ? $data->Items->Item->CustomerReviews->Review : null;
-        if (!empty($reviews)) {
-            $i = 0;
-            foreach ($reviews as $review) {
-                $result[$i]['Rating'] = (string)$review->Rating;
-                $result[$i]['Summary'] = (string)$review->Summary;
-                $result[$i]['Content'] = (string)$review->Content;
-                $result[$i]['Copyright'] = $this->getCopyright($isbn);
-                $i++;
-            }
-        }
-
-        // If we weren't able to extract any individual reviews, we'll have
-        // to resort to displaying results in an iframe.
-        if (empty($result)) {
-            $iframe = isset($data->Items->Item->CustomerReviews->IFrameURL)
-                ? (string)$data->Items->Item->CustomerReviews->IFrameURL
-                : null;
-            if (!empty($iframe)) {
-                // CSS for iframe (explicit dimensions needed for IE
-                // compatibility -- using 100% has bad results there):
-                $css = "width: 700px; height: 500px;";
-                // Replacement for http/https compatibility
-                $iframe = str_replace('http://', '//', $iframe);
-                $result[] = [
-                    'Rating' => '',
-                    'Summary' => '',
-                    'Copyright' => $this->getCopyright($isbn),
-                    'Content' =>
-                        "<iframe style=\"{$css}\" src=\"{$iframe}\"></iframe>"
-                ];
-            }
-        }
-
-        return $result;
-    }
-}
diff --git a/module/VuFind/src/VuFind/Content/Reviews/AmazonEditorial.php b/module/VuFind/src/VuFind/Content/Reviews/AmazonEditorial.php
deleted file mode 100644
index 16720deed7c..00000000000
--- a/module/VuFind/src/VuFind/Content/Reviews/AmazonEditorial.php
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php
-/**
- * Amazon review content loader.
- *
- * PHP version 7
- *
- * Copyright (C) Villanova University 2010.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * @category VuFind
- * @package  Content
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-namespace VuFind\Content\Reviews;
-
-use ZendService\Amazon\Amazon;
-
-/**
- * Amazon review content loader.
- *
- * @category VuFind
- * @package  Content
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-class AmazonEditorial extends \VuFind\Content\AbstractAmazon
-{
-    /**
-     * Amazon Editorial
-     *
-     * This method is responsible for connecting to Amazon AWS and abstracting
-     * editorial reviews for the specific ISBN
-     *
-     * @param string           $key     API key
-     * @param \VuFindCode\ISBN $isbnObj ISBN object
-     *
-     * @throws \Exception
-     * @return array     Returns array with review data.
-     * @author Andrew Nagy <vufind-tech@lists.sourceforge.net>
-     */
-    public function loadByIsbn($key, \VuFindCode\ISBN $isbnObj)
-    {
-        try {
-            $amazon = new Amazon($key, 'US', $this->secret);
-            $amazon->getRestClient()->setHttpClient($this->getHttpClient());
-            $params = [
-                'ResponseGroup' => 'EditorialReview',
-                'AssociateTag' => $this->associate
-            ];
-            $isbn = $this->getIsbn10($isbnObj);
-            $data = $amazon->itemLookup($isbn, $params);
-        } catch (\Exception $e) {
-            // Something went wrong?  Just return empty list.
-            return [];
-        }
-
-        if ($data) {
-            $i = 0;
-            $result = [];
-            $reviews = isset($data->EditorialReviews)
-                ? $data->EditorialReviews : null;
-            if (!empty($reviews)) {
-                foreach ($reviews as $review) {
-                    // Filter out product description
-                    if ((string)$review->Source != 'Product Description') {
-                        foreach ($review as $key => $value) {
-                            $result[$i][$key] = (string)$value;
-                        }
-                        if (!isset($result[$i]['Copyright'])) {
-                            $result[$i]['Copyright'] = $this->getCopyright($isbn);
-                        }
-                        $i++;
-                    }
-                }
-            }
-            return $result;
-        }
-    }
-}
diff --git a/module/VuFind/src/VuFind/Content/Reviews/PluginManager.php b/module/VuFind/src/VuFind/Content/Reviews/PluginManager.php
index 81e575fd1d3..be097fc5f21 100644
--- a/module/VuFind/src/VuFind/Content/Reviews/PluginManager.php
+++ b/module/VuFind/src/VuFind/Content/Reviews/PluginManager.php
@@ -46,8 +46,10 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager
      * @var array
      */
     protected $aliases = [
-        'amazon' => Amazon::class,
-        'amazoneditorial' => AmazonEditorial::class,
+        Amazon::class => Deprecated::class,
+        AmazonEditorial::class => Deprecated::class,
+        'amazon' => Deprecated::class,
+        'amazoneditorial' => Deprecated::class,
         'booksite' => Booksite::class,
         'demo' => Demo::class,
         'guardian' => Guardian::class,
diff --git a/module/VuFind/tests/fixtures/configs/amazoncover/config.ini b/module/VuFind/tests/fixtures/configs/amazoncover/config.ini
new file mode 100644
index 00000000000..4aa46b56d2c
--- /dev/null
+++ b/module/VuFind/tests/fixtures/configs/amazoncover/config.ini
@@ -0,0 +1,1896 @@
+;
+; VuFind Configuration
+;
+
+; This section controls global system behavior and can usually be left unmodified.
+[System]
+; Change to false to take the system offline and show an unavailability message;
+; note that you can use the NoILS driver (in [Catalog] section below) to keep VuFind
+; up during ILS maintenance.
+available       = true
+; Change to true to see messages about the behavior of the system as part of the
+; output -- only for use when troubleshooting problems. See also the access.DebugMode
+; setting in permissions.ini to turn on debug using a GET parameter in the request.
+debug           = false
+; This setting should be set to false after auto-configuration is complete
+autoConfigure = true
+; This setting specifies a health check file location. If a health check file exists,
+; the getServerStatus AJAX call will return an error regardless of actual status
+; allowing the server to be disabled from a load-balancer.
+;healthCheckFile = /tmp/disable_vufind
+
+; This section will need to be customized for your installation
+[Site]
+; Base URL is normally auto-detected, but this setting is used when autodetection is
+; not possible (i.e. during sitemap generation at the command line).
+url             = http://library.myuniversity.edu/vufind
+; Set to true if VuFind is behind a reverse proxy (typically Apache with mod_proxy),
+; make sure your reverse proxy sets the necessary headers.
+;reverse_proxy    = true
+email           = support@myuniversity.edu
+title           = "Library Catalog"
+; This is the default theme for non-mobile devices (or all devices if mobile_theme
+; is disabled below). Available standard themes:
+;   bootstrap3 = HTML5 theme using Bootstrap 3 + jQuery libraries, with minimal styling
+;   bootprint3 = bootstrap3 theme with more attractive default styling applied
+;                (named after the earlier, now-deprecated blueprint theme)
+;   sandal     = bootstrap3 theme with a "flat" styling applied (a newer look
+;                than bootprint3).
+theme           = bootprint3
+
+; Uncomment the following line to use a different default theme for mobile devices.
+; You may not wish to use this setting if you are using one of the Bootstrap-based
+; standard themes since they support responsive design.
+;mobile_theme    = mobile
+
+; Automatic asset minification and concatenation setting. When active, HeadScript
+; and HeadLink will concatenate and minify all viable files to reduce requests and
+; load times. This setting is off by default.
+;
+; This configuration takes the form of a semi-colon separated list of
+; environment:configuration pairs where "environment" is a possible APPLICATION_ENV
+; value (e.g. 'production' or 'development') or '*'/no prefix for all contexts.
+; Possible values for 'configuration' within each environment are 'js', 'css',
+; 'off'/false, 'on'/true/'*'. This allows global enabling/disabling of the pipeline
+; or separate configurations for different types of resources. Multiple configuration
+; values may be comma-separated -- e.g. 'js,css'.
+;
+; Example: "development:off; production:js,css"
+;asset_pipeline = "production:js"
+
+; This is a comma-separated list of themes that may be accessed via the ?ui GET
+; parameter.  Each entry has two parts: the value used on the URL followed by the
+; actual theme name.  For example, http://library.myuniversity.edu/vufind?ui=theme1
+; would load the myTheme1 theme with the setting shown below.  Note that the values
+; of "standard" and "mobile" are reserved for the default and mobile themes defined
+; above.
+;alternate_themes = theme1:myTheme1,theme2:myTheme2
+
+; This is a comma-separated list of theme options that will be displayed to the user
+; as a drop-down.  Each entry has two parts: a value for the "ui" GET parameter and
+; an on-screen description.  "standard" refers to the "theme" setting above, "mobile"
+; refers to the "mobile_theme" setting, and all other values must be defined in
+; alternate_themes above.  When commented out, no drop-down theme list will display.
+;selectable_themes = "standard:Standard Theme,mobile:Mobile Theme"
+
+; Use the browser language setting to set the VuFind language.
+browserDetectLanguage = true
+language        = en    ; default -- more options available in [Languages] below.
+locale          = en_US
+; Set this to specify a default ISO 4217 currency code (used on the fines screen).
+; If omitted, the default currency for the locale above will be used.
+;defaultCurrency = USD
+; Find valid timezone values here:
+;   http://www.php.net/manual/en/timezones.php
+timezone        = "America/New_York"
+; A string used to format user interface date strings using the PHP date() function
+; default is m-d-Y (MM-DD-YYYY 01-01-2010)
+displayDateFormat = "m-d-Y"
+; A string used to format user interface time strings using the PHP date() function
+; default is H:i (HH:MM 23:01)
+displayTimeFormat = "H:i"
+; The base VuFind URL will load this controller unless the user is logged in:
+defaultModule   = Search
+; When defaultModule is used, this action will be triggered (default = Home)
+;defaultAction = Home
+; The base VuFind URL will load this controller when the user is logged in:
+defaultLoggedInModule = MyResearch
+; When defaultLoggedInModule is used, this action will be triggered (default = Home)
+;defaultLoggedInAction = Home
+; The search backend that VuFind will use in search boxes when nothing else is
+; specified (e.g. on user account pages, search history, etc.). Default = Solr
+;defaultSearchBackend = Solr
+; The route VuFind will send users to following a log out operation. Set to false
+; or omit to attempt to retain the user's current context after log out.
+;logOutRoute = home
+; Default tab to display when a record is viewed (see also RecordTabs.ini):
+defaultRecordTab = Holdings
+; Hide the holdings tab if no holdings are available from the ILS; note that this
+; feature requires your ILS driver to support the hasHoldings() method.
+hideHoldingsTabWhenEmpty = false
+; Whether to load the default tab through AJAX (which brings some performance
+; gain but breaks compatibility with non-Javascript-enabled browsers; off by default)
+;loadInitialTabWithAjax = true
+; The holdingsTemplate to use to display the ILS holdings (defaults to standard).
+; See the templates/RecordTab/holdingsils subdirectory of your theme for options.
+;holdingsTemplate = extended
+; This page will show by default when a user accesses the MyResearch module:
+defaultAccountPage = Favorites
+; Allow access to the Admin module? (See the access.AdminModule setting in
+; permissions.ini for more granular ways to restrict Admin access).
+admin_enabled = false
+; Show sidebar on the left side instead of right
+sidebarOnLeft = false
+; Invert the sidebarOnLeft setting for right-to-left languages?
+mirrorSidebarInRTL = true
+; Put search result thumbnails on the left (true) or right (false)
+resultThumbnailsOnLeft = true
+; Put favorites list thumbnails on the left (true) or right (false)
+listThumbnailsOnLeft = true
+; Put hold/checkedout/ILL/etc. item thumbnails on the left (true) or right (false)
+accountThumbnailsOnLeft = true
+; Show thumbnail on opposite side in right-to-left languages?
+mirrorThumbnailsRTL = true
+; Handle menu as an offcanvas slider at mobile sizes (in bootstrap3-based themes)
+offcanvas = false
+; Show (true) / Hide (false) Book Bag - Default is Hide.
+showBookBag = false
+; Set the maximum amount of items allowed in the Book Bag - Default is 100
+bookBagMaxSize = 100
+; Show individual add/remove bookbag buttons in search results? (Supersedes cart
+; checkboxes and bulk action buttons unless showBulkOptions is true).
+bookbagTogglesInSearch = true
+; Display bulk items (export, save, etc.) and checkboxes on search result screens?
+showBulkOptions = false
+; Should users be allowed to save searches in their accounts?
+allowSavedSearches = true
+; Some VuFind features can be made compatible with non-Javascript browsers at
+; a performance cost. By default, this compatibility is disabled, but it can
+; be turned on here. Note that even with this setting turned on, some features
+; still require Javascript; this simply improves compatibility for certain
+; features (such as display of hierarchies).
+nonJavascriptSupportEnabled = false
+; Generator value to display in an HTML header <meta> tag:
+generator = "VuFind 6.1.1"
+
+; This section allows you to configure the mechanism used for storing user
+; sessions.  Available types: File, Memcache, Database, Redis.
+; Some of the settings below only apply to specific session handlers;
+; such settings are named with an obvious prefix.  Non-prefixed settings
+; are global to all handlers.
+[Session]
+type                        = File
+lifetime                    = 3600 ; Session lasts for 1 hour
+; Should stored session data be encrypted?
+secure = false
+; Keep-alive interval in seconds. When set to a positive value, the session is kept
+; alive with a JavaScript call as long as a VuFind page is open in the browser.
+; Default is 0 (disabled). When keep-alive is enabled, session lifetime above can be
+; reduced to e.g. 600.
+;keepAlive = 60
+;file_save_path              = /tmp/vufind_sessions
+;memcache_host               = localhost
+;memcache_port               = 11211
+;memcache_connection_timeout = 1
+;
+; Settings related to Redis-based sessions; default values are listed below
+;redis_host               = localhost
+;redis_port               = 6379
+;redis_connection_timeout = 0.5
+;redis_db                 = 0
+;redis_auth               = some_secret_password
+;redis_version            = 3
+;redis_standalone         = true
+
+; This section controls how VuFind creates cookies (to store session IDs, bookbag
+; contents, theme/language settings, etc.)
+[Cookies]
+; In case there are multiple VuFind instances on the same server and they should not
+; share cookies/sessions, this option can be enabled to limit the session to the
+; current path. Default is false, which will place cookies at the root directory.
+;limit_by_path = true
+; If VuFind is only accessed via HTTPS, this setting can be enabled to disallow
+; the browser from ever sending cookies over an unencrypted connection (i.e.
+; before being redirected to HTTPS). Default is false.
+;only_secure = true
+; Whether to set cookies set by the server (apart from cart function) "HTTP only" so
+; that they cannot be accessed by scripts. Default is true.
+;http_only = false
+; Set the domain used for cookies (sometimes useful for sharing the cookies across
+; subdomains); by default, cookies will be restricted to the current hostname.
+;domain = ".example.edu"
+; This sets the session cookie's name. Comment this out to use the default
+; PHP_SESS_ID value. If running multiple versions of VuFind (or multiple PHP
+; applications) on the same host, it is strongly recommended to give each a
+; different session_name setting to avoid data contamination.
+session_name = VUFIND_SESSION
+
+; Please set the ILS that VuFind will interact with.
+;
+; Available drivers:
+;   - Aleph
+;   - Alma
+;   - Amicus
+;   - DAIA (using either XML or JSON API)
+;   - Demo (fake ILS driver returning complex responses)
+;   - Evergreen
+;   - Folio
+;   - Horizon (basic database access only)
+;   - HorizonXMLAPI (more features via API)
+;   - Innovative (for INNOPAC; see also Sierra/SierraRest)
+;   - Koha (basic database access only)
+;   - KohaILSDI (more features via ILS-DI API)
+;   - LBS4
+;   - MultiBackend (to chain together multiple drivers in a consortial setting)
+;   - NewGenLib
+;   - NoILS (for users with no ILS, or to disable ILS features during maintenance),
+;   - PAIA
+;   - Polaris
+;   - Sample (fake ILS driver returning bare-minimum data)
+;   - Sierra (basic database access only)
+;   - SierraRest (more features via API)
+;   - Symphony (uses native SirsiDynix APIs)
+;   - Unicorn (also applies to Symphony; requires installation of connector found at:
+;     http://code.google.com/p/vufind-unicorn/)
+;   - Virtua
+;   - Voyager (database access only; for Voyager 6+)
+;   - VoyagerRestful (for Voyager 7+ w/ RESTful web services)
+;   - XCNCIP2 (for XC NCIP Tookit v2.x)
+;
+; If you haven't set up your ILS yet, two fake drivers are available for testing
+; purposes. "Sample" is fast but does very little; "Demo" simulates more
+; functionality of a real ILS but may slow down your system by performing extra
+; searches. If you don't plan to use an ILS, the NoILS driver is your best option.
+;
+; Note: Enabling most of the features in this section will only work if you use an
+; ILS driver that supports them; not all drivers support holds/renewals.
+[Catalog]
+driver          = Sample
+
+; loadNoILSOnFailure - Whether or not to load the NoILS driver if the main driver fails
+loadNoILSOnFailure = false
+
+; List of search backends that contain records from your ILS (defaults to Solr
+; unless set otherwise). You can set ilsBackends = false to disable ILS status
+; loading entirely.
+;ilsBackends[] = Solr
+
+; This setting determines how and when hold / recall links are displayed.
+; Legal values:
+; - all (Show links for all items - Place Hold for Available Items and Place Recall
+;   for unavailable items)
+; - availability (Only show recall links if ALL items on bib are currently
+;   unavailable)
+; - disabled (Never show hold/recall links)
+; - driver (Use ILS driver to determine which items may be held/recalled; best option
+;   if available, but not supported by all drivers)
+; - holds (Only show links for available items)
+; - recalls (Only show links for unavailable items)
+; default is "all"
+holds_mode = "all"
+
+; Set this to true if you want to allow your ILS driver to override your holds_mode
+; setting on a record-by-record basis; this may be useful for local customizations,
+; but in most cases you should leave this setting unchanged.  Overrides are ignored
+; for mode settings of "driver" or "disabled."
+allow_holds_override = false
+
+; Determines if holds can be cancelled or not. Options are true or false.
+; default is false
+cancel_holds_enabled = false
+
+; Determines if storage retrieval requests can be cancelled or not.
+; Options are true or false.
+; default is false
+cancel_storage_retrieval_requests_enabled = false
+
+; Determines if ILL requests can be cancelled or not.
+; Options are true or false.
+; default is false
+cancel_ill_requests_enabled = false
+
+; Determines if item can be renewed or not. Options are true or false.
+; default is false
+renewals_enabled = false
+
+; Determines if title level holds are displayed or not.
+; Legal values:
+; - disabled (Never show title Holds - Default)
+; - always (Always show title Holds)
+; - availability (Only show title holds if ALL items on bib are currently
+;   unavailable)
+; - driver (Use ILS driver to determine which items may be held/recalled; best option
+;   if available, but not supported by all drivers)
+title_level_holds_mode = "disabled"
+
+; Determines how holdings are grouped in the record display, using fields from
+; the item information provided by the ILS driver.
+;
+; Most commonly-used values:
+; - holdings_id,location (Use holdings record id if available, location name as
+;   secondary - Default)
+; - location (Use location name)
+;
+; See https://vufind.org/wiki/development:plugins:ils_drivers#getholding for
+; more options (though not every ILS driver supports every possible value).
+;
+; Note that there may also be driver-specific values outside of the specification,
+; such as:
+; - item_agency_id (XCNCIP2 driver's Agency ID, which may be useful in consortial
+;   environments)
+;
+; You may use multiple group keys (delimited by comma), e.g.,
+; - item_agency_id,location
+;holdings_grouping = holdings_id,location
+
+; Text fields such as holdings_notes gathered from items to be displayed in each
+; holdings group in the display order.
+; The default list is 'holdings_notes', 'summary', 'supplements' and 'indexes'. The
+; deprecated field 'notes' is used as an alias for 'holdings_notes'.
+; Note that displayed information depends on what the ILS driver returns.
+;holdings_text_fields[] = 'holdings_notes'
+;holdings_text_fields[] = 'summary'
+
+; Whether support for multiple library cards is enabled. Default is false.
+;library_cards = true
+
+; The number of checked out items to display per page; 0 for no limit (may cause
+; memory problems for users with huge numbers of items). Default = 50.
+;checked_out_page_size = 50
+
+; The number of historic loans to display per page; 0 for no limit (may cause
+; memory problems for users with a large number of historic loans). Default = 50
+;historic_loan_page_size = 50
+
+; Whether to display the item barcode for each loan. Default is false.
+;display_checked_out_item_barcode = true
+
+; This section controls features related to user accounts
+[Account]
+; Allow the user to set a home library through the Profile screen, which will
+; override ILS-provided default pickup locations throughout the system.
+set_home_library = true
+
+; Allow the user to "subscribe" to search history entries in order to receive
+; email notifications of new search results.
+schedule_searches = false
+
+; Should we always send a scheduled search email the first time we run notices
+; after a user has subscribed (true), or should we only send an email when there
+; is actually something new (false, default)
+force_first_scheduled_email = false
+
+; When schedule_searches is set to true, you can customize the schedule frequencies
+; here -- just use the number of days between notifications in the brackets. Labels
+; will be run through the translator.
+;scheduled_search_frequencies[0] = schedule_none
+;scheduled_search_frequencies[1] = schedule_daily
+;scheduled_search_frequencies[7] = schedule_weekly
+
+; This section allows you to determine how the users will authenticate.
+; You can use an LDAP directory, the local ILS (or multiple ILSes through
+; the MultiILS option), the VuFind database (Database), a hard-coded list of
+; access passwords (PasswordAccess), AlmaDatabase (combination
+; of VuFind database and Alma account), Shibboleth, SIP2, CAS, Facebook, Email or
+; some combination of these (via the MultiAuth or ChoiceAuth options).
+;
+; The Email method is special; it is intended to be used through ChoiceAuth in
+; combination with Database authentication (or any other method that reliably stores
+; the user's email address) to make it possible to log in by receiving an
+; authentication link at the email address stored in VuFind's database. Email is
+; also supported as the primary authentication mechanism for some ILS drivers (e.g.
+; Alma). In these cases, ChoiceAuth is not needed, and ILS should be configured as
+; the Authentication method; see the ILS driver's configuration for possible options.
+;
+; Also note that the Email method stores hashes in your database's auth_hash table.
+; You should run the "php $VUFIND_HOME/public/index.php util expire_auth_hashes"
+; utility periodically to clean out old data in this table.
+[Authentication]
+;method          = LDAP
+;method         = ILS
+method         = Database
+;method         = AlmaDatabase
+;method         = Shibboleth
+;method         = SIP2
+;method         = CAS
+;method         = MultiAuth
+;method         = ChoiceAuth
+;method         = MultiILS
+;method         = Facebook
+;method         = PasswordAccess
+;method         = Email
+
+; This setting only applies when method is set to ILS.  It determines which
+; field of the ILS driver's patronLogin() return array is used as the username
+; in VuFind's user database.  If commented out, it defaults to cat_username
+; (the recommended setting in most situations).
+;ILS_username_field = cat_username
+
+; Whether or not to hide the Login Options; not that even when this is set to
+; false, ILS driver settings may be used to conditionally hide the login. See
+; hideLogin in the [Settings] section of NoILS.ini for an example.
+hideLogin = false
+
+; When set to true, uses AJAX calls to annotate the account menu with
+; notifications (overdue items, total fines, etc.)
+enableAjax = true
+
+; When set to true, replicates the account menu as a drop-down next to the
+; account link in the header.
+enableDropdown = false
+
+; Set this to false if you would like to store local passwords in plain text
+; (only applies when method = Database or AlmaDatabase above).
+hash_passwords = false
+
+; Allow users to recover passwords via email (if supported by Auth method)
+; You can set the subject of recovery emails in your
+; language files under the term "recovery_email_subject"
+recover_password = false
+; Time (seconds) before another recovery attempt can be made
+recover_interval      = 60
+; Length of time before a recovery hash can no longer be used (expires)
+; Default: Two weeks
+recover_hash_lifetime = 1209600
+
+; Allow users to set change their email address (if supported by Auth method).
+; When turning this on, it is also strongly recommended to turn on verify_email
+; below.
+change_email = false
+
+; Allow users to set change their passwords (if supported by Auth method)
+change_password = true
+
+; Force users to verify their email address before being able to log in
+; (only if method=Database) or make changes to it (if change_email=true).
+; If you wish to customize the email messages used by the system, see the
+; translation strings starting with verify and change_notification, as well as
+; the notify-email-change.phtml and verify-email.phtml Email templates.
+verify_email = false
+
+; Set this to false if you would like to store catalog passwords in plain text
+encrypt_ils_password = false
+
+; This is the key used to encrypt and decrypt catalog passwords.  This must be
+; filled in with a random string value when encrypt_ils_passwords is set to true.
+ils_encryption_key = false
+
+; This is the algorithm used to encrypt and decrypt catalog passwords.
+; A symmetrical encryption algorithm must be used.
+; You can use openssl_get_cipher_methods() to see available options on your system.
+; Common choices: blowfish (default), aes
+; If you want to convert from one algorithm to another, run this from $VUFIND_HOME:
+;   php public/index.php util switch_db_hash oldhash:oldkey (or none) newhash:newkey
+;ils_encryption_algo = "blowfish"
+
+; This setting may optionally be uncommented to restrict the email domain(s) from
+; which users are allowed to register when using the Database or AlmaDatabase method.
+;domain_whitelist[] = "myuniversity.edu"
+;domain_whitelist[] = "mail.myuniversity.edu"
+
+; Specify default minimum and maximum password length (Auth method may override
+; this).
+;minimum_password_length = 4
+;maximum_password_length = 32
+; Specify default limit of accepted characters in the password. Allowed values
+; are "numeric", "alphanumeric" or a regular expression
+;password_pattern = "(?=.*\d)(?=.*[a-z])(?=.*[A-Z])"
+; Specify default hint about what the password may contain when using a regexp
+; pattern. May be text or a translation key. The "numeric" and "alphanumeric"
+; patterns have translated default hints.
+;password_hint = "Include both upper and lowercase letters and at least one number."
+
+; Uncomment this line to switch on "privacy mode" in which no user information
+; will be stored in the database. Note that this is incompatible with social
+; features, password resets, and many other features. It is not recommended for
+; use with "Database" or "AlmaDatabase" authentication, since the user will be
+; forced to create a new account upon every login.
+;privacy = true
+
+; Allow a user to delete their account. Default is false.
+;account_deletion = true
+; Whether comments added by a user are deleted when they remove their account.
+; Default is true.
+;delete_comments_with_user = false
+
+; See the comments in library/VF/Auth/MultiAuth.php for full details
+; on using multiple authentication methods.  Note that MultiAuth assumes login
+; with username and password, so some methods (i.e. Shibboleth) may not be
+; compatible.
+;[MultiAuth]
+;method_order   = ILS,LDAP
+;filters = "username:trim,password:trim"
+
+; Present two auth options on the login screen. Each choice given must also be
+; configured in its relevant section. (The code should allow for more than 2
+; choices, but styling would need to be expanded / modified)
+;
+; WARNING! This module does not account for the possibility that the auth
+; choices you present may return different usernames. You would want a user to
+; be able to log in via any method and see the same account. To make sure that
+; is the case, you should ensure that the usernames given by the authentication
+; methods themselves are the same for any given user.
+;[ChoiceAuth]
+;choice_order = Shibboleth,Database
+
+; This section defines the location/behavior of the Solr index and requires no
+; changes for most installations
+[Index]
+; url can also be an array of servers. If so, VuFind will try the servers one by one
+; until one can be reached. This is only useful for advanced fault-tolerant Solr
+; installations.
+url             = http://localhost:8080/solr
+; Default bibliographic record core
+default_core    = biblio
+; Default authority record core
+default_authority_core = authority
+; This setting needs to match the <maxBooleanClauses> setting in your solrconfig.xml
+; file; when VuFind has to look up large numbers of records using ID values, it may
+; have to restrict the size of its result set based on this limitation.
+maxBooleanClauses = 1024
+; This is the timeout in seconds when communicating with the Solr server.
+timeout = 30
+; This is the Dismax handler to use if nothing is specified in searchspecs.yaml.
+; You can choose dismax for standard Dismax (the default) or edismax for Extended
+; Dismax, or you can configure your own custom handler in solrconfig.xml.
+default_dismax_handler = dismax
+; This is the number of records to retrieve in a batch e.g. when building a record
+; hierarchy. A higher number results in fewer round-trips but may increase Solr's
+; memory usage. Default is 1000.
+;cursor_batch_size = 1000
+
+
+; Enable/Disable searching reserves using the "reserves" Solr core.  When enabling
+; this feature, you need to run the util/index_reserves.php script to populate the
+; new index.
+[Reserves]
+search_enabled  = false
+
+; This section requires no changes for most installations; if your SMTP server
+; requires authentication, you can fill in a username and password below.
+[Mail]
+host            = localhost
+port            = 25
+;username       = user
+;password       = pass
+; The server name to report to the upstream mail server when sending mail.
+;name = vufind.myuniversity.edu
+; If a login is required you can define which protocol to use for securing the
+; connection. If no explicit protocol ('tls' or 'ssl') is configured, a protocol
+; based on the configured port is chosen (587 -> tls, 487 -> ssl).
+;secure         = tls
+; This setting enforces a limit (in seconds) on the lifetime of an SMTP
+; connection, which can be useful when sending batches of emails, since it can
+; help avoid errors caused by server timeouts. Comment out the setting to disable
+; the limit.
+connection_time_limit = 60
+; Uncomment this setting to disable outbound mail but simulate success; this
+; is useful for interface testing but should never be used in production!
+;testOnly = true
+; If set to false, users can send anonymous emails; otherwise, they must log in first
+require_login   = true
+; Should we put the logged-in user's address in the "from" field by default?
+user_email_in_from = false
+; Should we put the logged-in user's address in the "to" field by default?
+user_email_in_to = false
+; Should the user be allowed to edit email subject lines?
+user_editable_subjects = false
+; How many recipients is the user allowed to specify? (use 0 for no limit)
+maximum_recipients = 1
+; Populate the "from" field with this value if user_email_in_from is false and/or no
+; user is logged in:
+;default_from = "no-reply@myuniversity.edu"
+; Should we hide the "from" field in email forms? If no from field is visible, emails
+; will be sent based on user_email_in_from and default_from above, with the email
+; setting from the [Site] section used as a last resort.
+disable_from = false
+; From field override. Setting this allows keeping the "from" field in email forms
+; but will only use it as a reply-to address. The address defined here is used as the
+; actual "from" address.
+; Note: If a feature explicitly sets a different reply-to address (for example,
+; Feedback forms), the original from address will NOT override that reply-to value.
+;override_from = "no-reply@myuniversity.edu"
+
+; Being a special case of mail message, sending record results via SMS ("Text this")
+; may be "enabled" or "disabled" ("enabled" by default).
+; Should you choose to leave it enabled, see also sms.ini for further
+; configuration options.
+sms = enabled
+
+; Set this value to "database" to shorten links sent via email/SMS and
+; store its path in the database (default "none").
+url_shortener = none
+
+; This section needs to be changed to match your database connection information
+[Database]
+; Connection string format is [platform]://[username]:[password]@[host]:[port]/[db]
+; where:
+; [platform] = database platform (mysql, oci8 or pgsql)
+; [username] = username for connection
+; [password] = password for connection (optional)
+; [host] = host of database server
+; [port] = port of database server (optional)
+; [db] = database name
+database          = mysql://root@localhost/vufind
+
+; If your database (e.g. PostgreSQL) uses a schema, you can set it here:
+;schema = schema_name
+
+; The character set of the database -- may be latin1 or utf8; utf8 is STRONGLY
+; RECOMMENDED and is the default if no value is set here.  You may need latin1
+; for compatibility with existing VuFind 1.x installations.
+;charset = utf8
+
+; Reduce access to a set of single passwords
+; This is only used when Authentication method is PasswordAccess. See above.
+; Recommended to be used in conjunction with very restricted permissions.ini settings
+; and with most social settings disabled
+;[PasswordAccess]
+; access_user is a map of users to passwords
+; entering a correct password will login as that user
+;access_user[user] = password
+;access_user[admin] = superpassword
+
+; LDAP is optional.  This section only needs to exist if the
+; Authentication Method is set to LDAP.  When LDAP is active,
+; host, port, basedn and username are required.
+;[LDAP]
+; Prefix the host with ldaps:// to use LDAPS; omit the prefix for standard
+; LDAP with TLS.
+;host            = ldap.myuniversity.edu
+;port            = 389       ; LDAPS usually uses port 636 instead
+; By default, when you use regular LDAP (not LDAPS), VuFind uses TLS security.
+; You can set disable_tls to true to bypass TLS if your server does not support
+; it. Note that this setting is ignored if you use ldaps:// in the host setting.
+;disable_tls     = false
+;basedn          = "o=myuniversity.edu"
+;username        = uid
+; separator string for mapping multi-valued ldap-fields to a user attribute
+; if no separator is given, only the first value is mapped to the given attribute
+;separator = ';'
+; Optional settings to map fields in your LDAP schema to fields in the user table
+; in VuFind's database -- the more you fill in, the more data will be imported
+; from LDAP into VuFind:
+;firstname       = givenname
+;lastname        = sn
+;email           = mail
+;cat_username    =
+;cat_password    =
+;college         = studentcollege
+;major           = studentmajor
+; If you need to bind to LDAP with a particular account before
+; it can be searched, you can enter the necessary credentials
+; here.  If this extra security measure is not needed, leave
+; these settings commented out.
+;bind_username   = "uid=username o=myuniversity.edu"
+;bind_password   = password
+
+; SIP2 is optional.  This section only needs to exist if the
+; Authentication Method is set to SIP2.
+;[SIP2]
+;host            = ils.myuniversity.edu
+;port            = 6002
+
+; Shibboleth is optional.  This section only needs to exist if the
+; Authentication Method is set to Shibboleth. Be sure to set up authorization
+; logic in the permissions.ini file to filter users by Shibboleth attributes.
+;[Shibboleth]
+; Server param with the identity provider entityID if a Shibboleth session exists.
+; If omitted, Shib-Identity-Provider is used.
+;idpserverparam = Shib-Identity-Provider
+; Optional: Session ID parameter for SAML2 single logout support. If omitted, single
+; logout support is disabled. Note that if SLO support is enabled, Shibboleth session
+; ID's are tracked in external_session table which may need to be cleaned up with the
+; expire_session_mappings command line utility. See
+; https://vufind.org/wiki/configuration:shibboleth for more information on how
+; to configure the single logout support.
+;session_id = Shib-Session-ID
+; Optional: you may set attribute names and values to be used as a filter;
+; users will only be logged into VuFind if they match these filters.
+;userattribute_1       = entitlement
+;userattribute_value_1 = urn:mace:dir:entitlement:common-lib-terms
+;userattribute_2       = unscoped-affiliation
+;userattribute_value_2 = member
+; Required: the attribute Shibboleth uses to uniquely identify users.
+;username              = persistent-id
+; Required: Shibboleth login URL.
+;login                 = https://shib.myuniversity.edu/Shibboleth.sso/Login
+; Optional: Shibboleth logout URL.
+;logout                = https://shib.myuniversity.edu/Shibboleth.sso/Logout
+; Optional: URL to forward to after Shibboleth login (if omitted,
+; defaultLoggedInModule from [Site] section will be used).
+;target                = https://shib.myuniversity.edu/vufind/MyResearch/Home
+; Optional: provider_id (entityId) parameter to pass along to Shibboleth login.
+;provider_id           = https://idp.example.edu/shibboleth-idp
+; Some or all of the following entries may be uncommented to map Shibboleth
+; attributes to user database columns:
+;cat_username = HTTP_ALEPH_ID
+;cat_password = HTTP_CAT_PASSWORD
+;email = HTTP_MAIL
+;firstname = HTTP_FIRST_NAME
+;lastname = HTTP_LAST_NAME
+;college = HTTP_COLLEGE
+;major = HTTP_MAJOR
+;home_library = HTTP_HOME_LIBRARY
+
+; CAS is optional.  This section only needs to exist if the
+; Authentication Method is set to CAS.
+;[CAS]
+
+; Optional: the attribute CAS uses to uniquely identify users. (Omit to use
+; native CAS username instead of an attribute-based value).
+;username              = uid
+
+; Required: CAS Hostname.
+;server                = cas.myuniversity.edu
+
+; Required: CAS port.
+;port                 = 443
+
+; Required: CAS context.
+;context                 = /cas
+
+; Required: CAS Certificate Path. (Set to false to bypass authentication;
+; BYPASSING AUTHENTICATION IS *NOT* RECOMMENDED IN PRODUCTION).
+;CACert = /etc/pki/cert/cert.crt
+
+; Required: CAS login URL.
+;login                 = https://cas.myuniversity.edu/cas/login
+
+; Required: CAS logout URL.
+;logout                = https://cas.myuniversity.edu/cas/logout
+
+; Optional: CAS logging.
+;debug              = false
+;log                = /tmp/casdebug
+
+; Optional: URL to forward to after CAS login (if omitted,
+; defaultLoggedInModule from [Site] section will be used).
+;target                = http://lib.myuniversity.edu/vufind/MyResearch/Home
+
+; Optional: protocol to follow (legal values include CAS_VERSION_1_0,
+; CAS_VERSION_2_0, CAS_VERSION_3_0 and SAML_VERSION_1_1; default is
+; SAML_VERSION_1_1)
+;protocol = SAML_VERSION_1_1
+
+; Some or all of the following entries may be uncommented to map CAS
+; attributes to user database columns:
+;cat_username = acctSyncUserID
+;cat_password = catPassword
+;email = mail
+;firstname = givenName
+;lastname = sn
+;college = college
+;major = major1
+;home_library = library
+
+; Facebook may be used for authentication; fill in this section in addition to
+; turning it on in [Authentication] above to use it. You must register your
+; VuFind instance as an application at http://developers.facebook.com to obtain
+; credentials.
+;[Facebook]
+;appId = "your app ID"
+;secret = "your app secret"
+
+; External Content is Optional.
+; To use multiple, separate with a comma.  Priority will be given by the order listed
+; Account id is separated with a colon, if no id is used then no colon is necessary
+; For Amazon, use your 20-character access key in the coverimages and reviews values;
+; you must also provide your 40-character secret key in the amazonsecret value and
+; your associate ID in the amazonassociate value.
+;
+; IMPORTANT: Review content providers' terms of service before turning them on.
+;            Terms may change, and not all content sources are appropriate for all
+;            applications.  The existence of functionality in VuFind does not imply
+;            suitability for any particular situation.
+[Content]
+; You can define the cover size used by each template: false (to disable covers)
+; or size (small, medium, or large). A colon separated list may be used to try
+; multiple sizes in a particular order. All legal template values and default
+; values are reflected in the examples below. Uncomment the appropriate lines to
+; make changes.
+;coversize[checkedout] = small
+;coversize[collection-info] = medium
+;coversize[core] = medium
+;coversize[holds] = small
+;coversize[illrequests] = small
+;coversize[list-entry] = small
+;coversize[RandomRecommend] = "small:medium"
+;coversize[result-grid] = large
+;coversize[result-list] = small
+;coversize[storageretrievalrequests] = small
+
+; Alternatively, if you wish to disable covers completely, you may set the
+; coversize setting to false:
+;coversize = false
+
+; You can select Syndetics, LibraryThing, Summon, Amazon, Booksite, OpenLibrary,
+; Contentcafe, Buchhandel.de, Google Books, BrowZine and/or LocalFile.
+;   Note: BrowZine requires you to have BrowZine.ini configured appropriately.
+;   Note: Summon service takes a Serials Solutions client key, NOT Summon API key!
+;   For LocalFile:PathToFile, you may use a combination of directory path information
+;        and tokens for filename and image type. If you have multiple directories
+;        in which you have stored coverimages, you can specify multiple paths to search
+;        by specifying multiple LocalFile:PathToFile in the coverage images list below.
+;        Allowed tokens:
+;          %anyimage%         - Match known image file extensions (gif, jpg, etc.)
+;          %isbn10%           - 10-digit ISBN
+;          %isbn13%           - 13-digit ISBN
+;          %issn%             - ISSN
+;          %oclc%             - OCLC Number
+;          %recordid%         - Bibliographic record ID
+;          %size%             - Size (small/medium/large)
+;          %source%           - Search backend of record (e.g. Summon, Solr, etc.)
+;          %upc%              - UPC Number
+;          %vufind-home%      - The VUFIND_HOME environment variable
+;          %vufind-local-dir% - The VUFIND_LOCAL_DIR environment variable
+;        Example: LocalFile:%vufind-local-dir%/path/to/file/%size%/issn/%issn%.%anyimage%
+coverimages     = Syndetics:MySyndeticsId,Amazon:MyAccessKeyId,Booksite,LibraryThing:MyLibraryThingId,Google,OpenLibrary,Summon:MySerialsSolutionsClientKey,Contentcafe:MyContentCafeID,BrowZine,LocalFile:PathToFile
+
+; This setting controls which services will have images cached on your local disk.
+; Set to true to cache all applicable services. Set to false to disable caching. Set
+; to a comma-separated list of services (e.g. "Syndetics,OpenLibrary") to cache only
+; a subset of selected services. Default = true. Note that due to terms of service,
+; some services will never have images cached even if caching is enabled.
+coverimagesCache = true
+
+; This setting controls which proxied image URLs will be cached to local disk (when
+; using the ?proxy= parameter of the standard /Cover/Show routes). The setting may
+; contain one or more regular expressions matching hostnames. The example
+; below will match any images from the mylibrary.edu domain; you can also use
+; "/.*/" to turn on caching for all proxied images.
+;coverproxyCache[] = "/.*\.?mylibrary\.edu/"
+
+; These settings control the image to display when no book cover is available.
+; If makeDynamicCovers is not false and the GD library is installed, VuFind will draw
+; cover images on the fly. See [DynamicCovers] below for more settings. If set to
+; a non-Boolean value, for legacy reasons, the makeDynamicCovers setting will
+; be used as the backgroundMode setting of [DynamicCovers] if that setting is unset.
+;makeDynamicCovers = true
+
+; Otherwise, you can use noCoverAvailableImage to specify a
+; path relative to the base of your theme directory for a static image to display.
+noCoverAvailableImage = images/noCover2.gif
+
+; You can select from Syndetics, SyndeticsPlus, Amazon Editorial, Amazon, Booksite
+; and/or the Guardian
+;   Note: If the API key is omitted, e.g. "Guardian:", only the review title, byline,
+;         Guardian logo and a link to the full Guardian page will be displayed
+;   Note: The Guardian API changed in 2014; if you signed up before that date, you
+;         may need to obtain a new API key for continued access.
+;reviews         = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsID,AmazonEditorial:MyAccessKeyId,Amazon:MyAccessKeyId,Booksite,Guardian:MyGuardianKeyId
+
+; You can select from Syndetics or SyndeticsPlus
+;excerpts        = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsId
+
+; This setting can be used to hide review/excerpt tabs on the record page when
+; no content is available from the providers. By default it is turned off. You
+; can turn it on for all relevant tabs by setting it to true, or you can turn
+; it on for a comma-separated list of values (e.g. "reviews" or "excerpts" or
+; "reviews,excerpts") for selective activation. Note that hiding empty tabs will
+; make your record pages slower, since it will require extra communication with
+; content providers.
+;hide_if_empty = reviews,excerpts
+
+; You can select from Syndetics or SyndeticsPlus to add summary information to
+; the description tab.
+;summaries = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsId
+
+; You can select from Syndetics or SyndeticsPlus to load Tables of Contents
+;toc = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsId
+
+; You can select from Syndetics or SyndeticsPlus
+;authorNotes = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsId
+
+; You can select from Wikipedia
+; See also the AuthorInfo recommendation module setting in searches.ini; this
+; includes notes on improving the accuracy of Wikipedia retrievals.
+; Note for Windows users: If using Wikipedia, you may need to increase your Apache
+; heap size settings.  For details, see: https://vufind.org/jira/browse/VUFIND-630
+authors         = Wikipedia
+
+; You can look up your secret key by logging into http://aws.amazon.com and clicking
+; "Access Identifiers" under "Your Account".
+;amazonsecret    = MyAmazonSecretKey
+
+; You can sign up for an associate ID by logging into
+; https://affiliate-program.amazon.com .  Please make sure your instance of VuFind
+; complies with Amazon's agreements before enabling this feature.
+;amazonassociate = MyAmazonAssociateID
+
+; You can select from Google, OpenLibrary, HathiTrust.  You should consult
+; https://developers.google.com/books/branding before using Google Book Search.
+;previews       = Google,OpenLibrary,HathiTrust
+
+; This setting controls whether or not cover images are linked to previews when
+; available. Legal settings are false (never link), * (always link; default), or
+; a comma-separated list of templates in which linking should occur (see coversize
+; above for a list of legal values).
+;linkPreviewsToCovers = *
+
+; Possible HathiRights options = pd,ic,op,orph,und,umall,ic-world,nobody,pdus,cc-by,cc-by-nd,
+; cc-by-nc-nd,cc-by-nc,cc-by-nc-sa,cc-by-sa,orphcand,cc-zero,und-world,icus
+; Default is "pd,ic-world" if unset here.
+; See www.hathitrust.org/rights_database#Attributes for full details
+;HathiRights    = pd,ic-world,cc-by,cc-by-nd,cc-by-nc-nd,cc-by-nc,cc-by-nc-sa,cc-by-sa,cc-zero,und-world
+
+; Possible GoogleBooks options full,partial,noview
+; options can be set for each / either of link or tab
+; Link makes a button appear in search results / record view
+; Tab makes a tab with an embedded preview appear on record view
+; Default is "GoogleOptions['link'] = full,partial" if nothing
+; is set here.
+; see https://developers.google.com/books/docs/dynamic-links#json-results-format
+;GoogleOptions['link']  = full,partial
+;GoogleOptions['tab']  = partial
+
+; OpenLibrary currently offers the same options/default as GoogleBooks (above):
+;OpenLibraryOptions  = full,partial
+
+; An API key is needed to interact with the Europeana API (see the EuropeanaResults
+; recommendation module in searches.ini for more information)
+;europeanaAPI = INSERTKEY
+
+; Geographic Display
+; These configuration settings have been superseded by the geofeatures.ini file.
+; See the [MapTab] section of the geofeatures.ini file for more information.
+
+; This section controls the behavior of the cover generator when makeDynamicCovers
+; above is non-false.
+;
+; Note that any of these settings may be filtered to be size-specific by subscripting
+; the key with a size. You can use a key of * for a default to use when a specific
+; size is not matched. This allows adjustment of certain elements for different
+; thumbnail sizes. See the "size" setting below for an example.
+[DynamicCovers]
+; This controls the background layer of the generated image; options:
+; - solid: display a solid color
+; - grid: display a symmetrical random pattern seeded by title/callnumber
+;backgroundMode = grid
+
+; This controls the text layer of the generated image; options:
+; - default: display a title at the top and an author at the bottom
+; - initial: display only the first letter of the title as a stylized initial
+;textMode = default
+
+; Font files specified here should exist in the css/font subdirectory of a theme.
+; Some options are available by default inside the root theme.
+;authorFont = "Roboto-Light.ttf"
+;titleFont = "RobotoCondensed-Bold.ttf"
+
+; In 'default' textMode, covers are generated using title and author name; VuFind
+; will try to display everything by doing the following: break the title into
+; lines, and if the title is too long (more than maxTitleLines lines), it will
+; display ellipses at the last line.
+;
+; All text will be drawn using the specified textAlign alignment value using the
+; relevant titleFontSize or authorFontSize setting, except that author names will
+; be reduced to the minAuthorFontSize option if needed, and if that doesn't make
+; it fit, text will be aligned left and truncated.
+;
+; When using 'initial' textMode, maxTitleLines and author-related settings are
+; ignored as they do not apply.
+;textAlign = center
+;titleFontSize = 9
+;authorFontSize = 8
+;minAuthorFontSize = 7
+;maxTitleLines = 4
+
+; All color options support the same basic set of values:
+; - The 16 named colors from HTML4
+; - Arbitrary HTML hex colors in the form #RRGGBB (e.g. #FFFF00 for yellow)
+; Some color options also support additional options.
+; - authorFillColor,titleFillColor: the main color used
+; - authorBorderColor,titleBorderColor: the color used to make a border; "none" is
+;   a legal option in addition to colors.
+; - baseColor: When using grid backgrounds, you may also choose a base color drawn
+;   beneath the grid. Default is white.
+; - accentColor: When using solid backgrounds, this is the background color; when
+;   using grid backgrounds, this is the color of the grid pattern beneath the text.
+;   You may set this to "random" to select a random color seeded with text from
+;   the cover and adjusted with the "lightness" and "saturation" settings below.
+;titleFillColor = black
+;titleBorderColor = none
+;authorFillColor = white
+;authorBorderColor = black
+;baseColor = white
+;accentColor = random
+; Note: lightness and saturation are only used when accentColor = random. Legal
+; ranges are 0-255 for each value.
+;lightness = 220
+;saturation = 80
+
+; These settings control the size of the image -- if size is a single number, a
+; square will be created; if it is a string containing an "x" (i.e. 160x190) it
+; defines a WxH rectangle. wrapWidth constrains the text size (and must be no
+; larger than the width of the canvas). topPadding and bottomPadding push the
+; text away from the edges of the canvas.
+;size[*] = 128
+;size[medium] = 200
+;size[large] = 500
+;topPadding = 19
+;bottomPadding = 3
+;wrapWidth = 110
+
+; This section is needed for Buchhandel.de cover loading. You need an authentication
+; token. It may also be necessary to customize your templates in order to comply with
+; terms of service; please look at http://info.buchhandel.de/handbuch_links for
+; details before turning this on.
+[Buchhandel]
+url = "https://api.vlb.de/api/v1/cover/"
+; token = "XXXXXX-XXXX-XXXXX-XXXXXXXXXXXX"
+
+[QRCode]
+; This setting controls the image to display when no qrcode is available.
+; The path is relative to the base of your theme directory.
+;noQRCodeAvailableImage = images/noQRCode.gif
+
+; Should we show QR codes in search results?
+;showInResults = true
+
+; Should we show QR codes on record pages?
+;showInCore = true
+
+; If you are using Syndetics Plus for *any* content, set plus = true
+; and set plus_id to your syndetics ID.  This loads the javascript file.
+; Syndetics vs. SyndeticsPlus: SyndeticsPlus has nice formatting, but loads slower
+; and requires javascript to be enabled in users' browsers.
+; set use_ssl to true if you serve your site over ssl and you
+; use SyndeticsPlus to avoid insecure content browser warnings
+; (or if you just prefer ssl)
+; NOTE: SyndeticsPlus is incompatible with the tabs/accordion [List] views in
+;       searches.ini. Do not turn it on if you are using these optional features.
+[Syndetics]
+use_ssl = false
+plus = false
+;plus_id = "MySyndeticsId"
+; timeout value (in seconds) for API calls:
+timeout = 10
+
+; Booksite CATS Enhanced Content - cover images, reviews, description, etc.
+[Booksite]
+url = "https://api.booksite.com"
+;key = "XXXXXXXXXXXXXXXXX"
+
+; Content Cafe is a subscription service from Baker & Taylor. If you are using this
+; service (see the [Content] section above for details), you MUST uncomment and set
+; the password (pw) setting. You may also change the API base URL (url) if needed.
+[Contentcafe]
+;url              = "http://contentcafe2.btol.com"
+;pw               = "xxxxxx"
+
+; Summon is optional; this section is used for your API credentials. apiId is the
+; short, human-readable identifier for your Summon account; apiKey is the longer,
+; non-human-readable secret key. See also the separate Summon.ini file.
+;[Summon]
+;apiId        = myAccessId
+;apiKey       = mySecretKey
+
+; This section must be filled in if you plan to use the optional WorldCat
+; search module. Otherwise, it may be ignored.
+;[WorldCat]
+;Your WorldCat search API key
+;apiKey          = "long-search-api-key-goes-here"
+;Your holdings symbol (usually a three-letter code) - used for excluding your
+; institution's holdings from the search results.
+;OCLCCode        = MYCODE
+
+; This section must be filled in to use Relais (E-ZBorrow) functionality. When
+; activated, this function will allow users to place ILL requests on unavailable
+; items through the record holdings tab.
+;
+; If you set apikey below, requests may be made from within VuFind through a
+; pop-up; if you omit apikey but set loginUrl and symbol, links will be provided
+; to Relais. Setting loginUrl and symbol is strongly recommended in all cases,
+; since links will be used as a fallback if the API fails.
+;[Relais]
+; Your library's holdings symbol (e.g. PVU for Villanova)
+;symbol="XYZ"
+; The pickup location to use for your institution (currently multiple pickup
+; locations are not supported here).
+;pickupLocation = "DEFAULT"
+; Barcode number (or other user ID) to use for lookups when none is provided
+;patronForLookup="99999999"
+; API key (may vary for testing vs. production)
+;apikey="your-relais-api-key-goes-here"
+; Timeout for HTTP requests (in seconds; set high, as Relais can be slow)
+;timeout = 500
+; Your institution's login URL for the remote Relais system (used to provide
+; a link when the API fails)
+;loginUrl = https://e-zborrow.relais-host.com/user/login.html
+
+; TEST VALUES (uncomment for testing)
+;group="DEMO"
+;authenticateurl="https://demo.relais-host.com/portal-service/user/authentication"
+;availableurl="https://demo.relais-host.com/dws/item/available"
+;addurl="https://demo.relais-host.com/dws/item/add"
+
+; PRODUCTION VALUES (uncomment for live use)
+;group="EZB"
+;authenticateurl="https://e-zborrow.relais-host.com/portal-service/user/authentication"
+;availableurl="https://e-zborrow.relais-host.com/dws/item/available"
+;addurl="https://e-zborrow.relais-host.com/dws/item/add"
+
+; DPLA key -- uncomment and fill in to use DPLATerms recommendations (see also
+; searches.ini).
+;[DPLA]
+;apiKey = http://dp.la/info/developers/codex/policies/#get-a-key
+
+; These settings affect dynamic DOI-based link inclusion; this can provide links
+; to full text or contextual information.
+[DOI]
+; This setting controls whether or not DOI-based links are enabled, and which
+; API is used to fetch the data. Currently supported options: BrowZine (requires
+; credentials to be configured in BrowZine.ini), Unpaywall or false (to disable). Disabled
+; by default.
+;resolver = BrowZine
+
+;unpaywall_api_url = "https://api.unpaywall.org/v2"
+; Unpaywall needs an email adress, see https://unpaywall.org/products/api
+;unpaywall_email = "your@email.org"
+
+; The following settings control where DOI-based links are displayed:
+show_in_results = true      ; include in search results
+show_in_record = false      ; include in core record metadata
+show_in_holdings = false    ; include in holdings tab of record view
+
+; These settings affect OpenURL generation and presentation; OpenURLs are used to
+; help users find resources through your link resolver and to manage citations in
+; Zotero.
+[OpenURL]
+; If a resolver base URL is enabled, it will be used to link from records to your
+; OpenURL resolver. An OpenURL resolver is typically used to e.g. link to full text
+; from article metadata, but it may provide other services too. Extra parameters may
+; be added if necessary.
+;url             = "http://openurl.myuniversity.edu/sfx_local"
+
+; This string will be included as part of your OpenURL referer ID (the full string
+; will be "info:sid/[your rfr_id setting]:generator").  You may be able to configure
+; special behavior in your link resolver based on this ID -- for example, you may
+; wish to prevent the resolver from linking to VuFind when links came from VuFind
+; (to avoid putting a user in an infinite loop).
+rfr_id          = vufind.svn.sourceforge.net
+
+; By specifying your link resolver type, you can allow VuFind to optimize its
+; OpenURLs for a particular platform.  Current legal values: "sfx", "360link",
+; "EZB", "Redi", "Alma", "demo" or "generic" (default is "generic" if commented out;
+; "demo" generates fake values for use in testing the embed setting below).
+;resolver        = sfx
+
+; If you want OpenURL links to open in a new window, set this setting to the
+; desired Javascript window.open parameters.  If you do not want a new window
+; to open, set this to false or comment it out.
+window_settings = "toolbar=no,location=no,directories=no,buttons=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=550,height=600"
+
+; If you want to display a graphical link to your link resolver, uncomment the
+; settings below.  graphic should be a URL; graphic_width and graphic_height
+; should be sizes in pixels.
+;graphic = "http://myuniversity.edu/images/findIt.gif"
+;graphic_width = 50
+;graphic_height = 20
+
+; If your link resolver can render an image in response to an OpenURL, you can
+; specify the base URL for image generation here:
+;dynamic_graphic = "http://my-link-resolver/image"
+
+; If dynamic_graphic is set above, the dynamic image can be used instead of the
+; standard text or static-image-based OpenURL link (true), it can be disabled
+; (false), or it can be displayed in addition to the regular link ("both").
+;image_based_linking_mode = both
+
+; The following settings control where OpenURL links are displayed:
+show_in_results = true      ; include in search results
+show_in_record = false      ; include in core record metadata
+show_in_holdings = false    ; include in holdings tab of record view
+
+; If set to true, this setting will attempt to embed results from the link
+; resolver directly in search results instead of opening a new window or page.
+; This will override the window_settings option if set! Embedding is currently
+; unsupported when the resolver setting above is set to "other".
+embed = false
+
+; When embed is true and this is set to true results from the link resolver will
+; be loaded automatically (default is false, which requires a user click to trigger
+; the loading). Alternatively you can provide a comma-separated list of view areas
+; (cf. show_in_* settings) to autoload embedded OpenURLs only in certain views.
+; Notice: autoloading in results view might put some load on your linkresolver (each
+; results view could perform searches.ini->[General]->default_limit requests). You
+; might reduce load on the linkresolver by using the resolver_cache setting (see
+; below).
+embed_auto_load = false
+
+; When embed is true, you can set this to an absolute path on your system in order
+; to cache link resolver results to disk.  Be sure that the chosen directory has
+; appropriate permissions set!  Leave the setting commented out to skip caching.
+; Note that the contents of this cache will not be expired by VuFind; you should
+; set up an external process like a cron job to clear out the directory from time
+; to time.
+;resolver_cache = /usr/local/vufind/resolver_cache
+
+; This setting controls whether we should display an OpenURL link INSTEAD OF other
+; URLs associated with a record (true) or IN ADDITION TO other URLs (false).
+replace_other_urls = true
+
+; EZproxy is optional.  This section only needs to exist if you
+; are using EZProxy to provide off-site access to online materials.
+;[EZproxy]
+;host            = http://proxy.myuniversity.edu
+
+; By default, when the 'host' setting above is active, VuFind will prefix links in
+; records using EZproxy's "?qurl=" mechanism. If you need to set a host for ticket
+; authentication (below) but you want to disable the prefixing behavior, set this
+; to false.
+;prefixLinks = true
+
+; Uncomment the following line and change the password to something secret to enable
+; EZproxy ticket authentication.
+;secret = "verysecretpassword"
+;
+; To enable ticket authentication in EZproxy, you will also need the following in
+; EZproxy's user.txt or ezproxy.usr for older versions (without the leading
+; semicolons and spaces):
+;
+; ::CGI=https://vufind-server/ExternalAuth/EzproxyLogin?url=^R
+; ::Ticket
+; TimeValid 10
+; SHA512 verysecretpassword
+;
+; Uncomment and modify the following line to use another hashing algorithm with the
+; EZproxy authentication if necessary. SHA512 is the default, but it requires at
+; least EZproxy version 6.1. Use "SHA1" for older EZproxy versions, and remember to
+; replace SHA512 with SHA1 also in EZproxy's configuration file.
+;secret_hash_method = "SHA512"
+
+; Uncomment the following line to disable relaying of user name to EZproxy on ticket
+; authentication:
+;anonymous_ticket = true
+; Uncomment the following line to disable logging of successful ticket
+; authentication requests in VuFind:
+;disable_ticket_auth_logging = true
+
+; These settings affect RefWorks record exports.  They rarely need to be changed.
+[RefWorks]
+vendor          = VuFind
+url             = https://www.refworks.com
+
+; These settings affect EndNote Web record exports.  They rarely need to be changed.
+[EndNoteWeb]
+vendor          = VuFind
+url             = https://www.myendnoteweb.com/EndNoteWeb.html
+
+; These settings affect your OAI server if you choose to use it.
+;
+; If identifier is set, its value will be used as part of the standard OAI
+; identifier prefix.  It should only ever be set to a domain name that you
+; control!  If it is not set, your ID values will not be prefixed.
+;
+; If admin_email is not set, the main email under [Site] will be used instead.
+;
+; page_size may be used to specify the number of records returned per request.
+; Default is 100. A higher number may improve overall harvesting performance, but
+; will also make a single response page larger and slower to produce.
+;
+; If set_field is set, the named Solr field will be used to generate sets on
+; your OAI-PMH server.  If it is not set, sets will not be supported.
+;
+; If set_query is set (as an array mapping set names to Solr queries -- see
+; examples below), the specified queries will be exposed as OAI sets.  If
+; you use both set_field and set_query, be careful about the names you choose
+; for your set queries. set_query names will trump set_field values when
+; there are collisions.
+;
+; default_query may be used to specify a filter for the default set, i.e. records
+; returned when a set is not specified.
+;
+; If vufind_api_format_fields is set, the listed fields (as defined in
+; SearchApiRecordFields.yaml) are returned when metadata prefix
+; "oai_vufind_json" is used.
+;
+; record_format_filters allows mapping from requested OAI metadataPrefix to query
+; filters. They can be used e.g. to limit results to records that can be returned in
+; the requested format.
+;
+; delete_lifetime controls how many days' worth of deleted records to include in
+; responses. Records deleted before the cut-off will not be included in responses.
+; Omit this setting to return all deleted records. This can be useful for long-lived
+; systems with many deleted records, to prevent full harvests from becoming unwieldy.
+;
+;[OAI]
+;identifier       = myuniversity.edu
+;repository_name  = "MyUniversity Catalog"
+;admin_email      = oai@myuniversity.edu
+;page_size        = 1000
+;set_field        = "format"
+;set_query['eod_books'] = "institution:kfu AND publishDate:[1911 TO 1911]"
+;set_query['eod_ebooks'] = "format:eBook"
+;default_query = "institution:kfu"
+;vufind_api_format_fields = "id,authors,cleanIsbn,cleanIssn,formats,title"
+;record_format_filters[marc21] = "record_format:marc"
+;delete_lifetime = 365
+
+; Proxy Server is Optional.
+[Proxy]
+;host = your.proxy.server
+;port = 8000
+
+; Uncomment following line to set proxy type to SOCKS 5
+;type = socks5
+
+; Default HTTP settings can be loaded here. These values will be passed to
+; the \Zend\Http\Client's setOptions method.
+[Http]
+;sslcapath = "/etc/ssl/certs" ; e.g. for Debian systems
+;sslcafile = "/etc/pki/tls/cert.pem" ; e.g. for CentOS systems
+
+;timeout = 30 ; default timeout if not overridden by more specific code/settings
+
+; Example: Using a CURL Adapter instead of the the defaultAdapter (Socket); note
+; that you may also need to install CURL and PHP/CURL packages on your server.
+;adapter = 'Zend\Http\Client\Adapter\Curl'
+
+; Spelling Suggestions
+;
+; Note: These settings affect the VuFind side of spelling suggestions; you
+; may also wish to adjust some Solr settings in solr/biblio/conf/schema.xml
+; and solr/biblio/conf/solrconfig.xml.
+[Spelling]
+enabled = true
+; Number of suggestions to display on screen. This list is filtered from
+;   the number set in solr/biblio/conf/solrconfig.xml so they can differ.
+limit   = 3
+; Show the full modified search phrase on screen
+;   rather then just the suggested word
+phrase = false
+; Offer expansions on terms as well as basic replacements
+expand  = true
+; Turning on 'simple' spell checking will improve performance,
+;  by ignoring the more complicated 'shingle' (mini phrases)
+;  based dictionary.
+simple = false
+; This setting skips spell checking for purely numeric searches; spelling
+; suggestions on searches for ISBNs and OCLC numbers are not generally very
+; useful.
+skip_numeric = true
+
+; These settings control what events are logged and where the information is
+; stored.
+;
+; VuFind currently supports four logging levels: alert (severe fatal error),
+; error (fatal error), notice (non-fatal warning) and debug (informational).
+;
+; Each logging level can be further broken down into five levels of verbosity.
+; You can specify the desired level by adding a dash and a number after the
+; level in the configuration string -- for example, alert-2 or error-5.
+; The higher the number, the more detailed the logging messages.  If verbosity
+; is not specified, it defaults to 1 (least detailed).
+;
+; Several logging methods are available, and each may be configured to log any
+; combination of levels.
+;
+; You may enable multiple logging mechanisms if you want -- in fact, it is
+; recommended, since the failure of one logging mechanism (i.e. database down,
+; file system full) may then be reported to another.
+;
+; If database is uncommented, messages will be logged to the named MySQL table.
+; The table can be created with this SQL statement:
+; CREATE TABLE log_table ( id INT NOT NULL AUTO_INCREMENT,
+;     logtime TIMESTAMP NOT NULL, ident CHAR(16) NOT NULL,
+;     priority INT NOT NULL, message TEXT, PRIMARY KEY (id) );
+;
+; If file is uncommented, messages will be logged to the named file.  Be sure
+; that Apache has permission to write to the specified file!
+;
+; If email is uncommented, messages will be sent to the provided email address.
+; Be careful with this setting: a flood of errors can easily bog down your mail
+; server!
+[Logging]
+;database       = log_table:alert,error,notice,debug
+; NOTE : Make sure the log file exists and that Apache has write permission.
+; NOTE : Windows users should avoid drive letters (eg. c:\vufind) because
+;        the colon will be used in the string parsing. "/vufind" will work
+;file           = /var/log/vufind.log:alert,error,notice,debug
+;email          = alerts@myuniversity.edu:alert-5,error-5
+
+; Get URL from https://YOURSLACK.slack.com/apps/manage/custom-integrations
+;slack = #channel_name:alert,error
+;slackurl = https://hooks.slack.com/services/your-private-details
+;slackname = "VuFind Log" ; username messages are posted under
+; You can also use the Slack settings to hook into Discord:
+; - Get your url from Server Settings > Webhooks
+; - Add /slack to the end of your url for Slack-compatible messages
+; https://discordapp.com/developers/docs/resources/webhook#execute-slackcompatible-webhook
+
+; This section can be used to specify a "parent configuration" from which
+; the current configuration file will inherit.  You can chain multiple
+; configurations together if you wish.
+[Parent_Config]
+; Full path to parent configuration file:
+;path = /usr/local/vufind/application/config/config.ini
+; Path to parent configuration file (relative to the location of this file):
+;relative_path = ../masterconfig/config.ini
+
+; A comma-separated list of config sections from the parent which should be
+; completely overwritten by the equivalent sections in this configuration;
+; any sections not listed here will be merged on a section-by-section basis.
+;override_full_sections = "Languages,AlphaBrowse_Types"
+
+; This setting is for allowing arrays to be merged with the values of their parents
+; arrays. If override_full_sections is set for a section the arrays will always be
+; overridden.
+; For legacy reasons merging of arrays is disabled by default.
+;merge_array_settings = false
+
+; This section controls which language options are available to your users.
+; If you offer more than one option, a control will appear in the user
+; interface to allow user selection.  If you only activate one language,
+; the control will be hidden.
+;
+; The name of each setting below (i.e. en, de, fr) is a language code and
+; corresponds with one of the translation files found in the web/lang
+; directory.  The value of each setting is the on-screen name of the language,
+; and will itself be subject to translation through the language files!
+;
+; The order of the settings is significant -- they will be displayed on screen
+; in the same order they are defined here.
+;
+; Be sure that this section includes the default language set in the [Site]
+; section above.
+[Languages]
+en          = "English"              ; American spellings
+;en-gb       = "English"              ; British spellings
+de          = "German"
+es          = "Spanish"
+fr          = "French"
+it          = "Italian"
+ja          = "Japanese"
+nl          = "Dutch"
+;nl-be       = "Flemish Dutch"
+pt          = "Portuguese"
+pt-br       = "Brazilian Portugese"
+zh-cn       = "Simplified Chinese"
+zh          = "Chinese"
+tr          = "Turkish"
+he          = "Hebrew"
+ga          = "Irish"
+cy          = "Welsh"
+el          = "Greek"
+ca          = "Catalan"
+eu          = "Basque"
+ru          = "Russian"
+cs          = "Czech"
+fi          = "Finnish"
+sv          = "Swedish"
+pl          = "Polish"
+da          = "Danish"
+sl          = "Slovene"
+ar          = "Arabic"
+bn          = "Bengali"
+gl          = "Galician"
+vi          = "Vietnamese"
+hr          = "Croatian"
+hi          = "Hindi"
+
+; This section contains special cases for languages such as right-to-left support
+[LanguageSettings]
+; Comma-separated list of languages to display in right-to-left mode
+rtl_langs = "ar,he"
+
+; This section controls the behavior of the Browse module.  The result_limit
+; setting controls the maximum number of results that may display in any given
+; result box on the Browse screen.  You can set to -1 for no limit; however,
+; setting a very high (or no) limit may result in "out of memory" errors if you
+; have a large index!
+[Browse]
+result_limit    = 100
+tag             = true      ; allow browsing of Tags
+dewey           = false     ; allow browsing of Dewey Decimal call numbers
+lcc             = true      ; allow browsing of LC call numbers
+author          = true      ; allow browsing of authors
+topic           = true      ; allow browsing of subject headings
+genre           = true      ; allow browsing of genre subdivisions
+region          = true      ; allow browsing of region subdivisions
+era             = true      ; allow browsing of era subdivisions
+; You can use this setting to change the default alphabet provided for browsing:
+;alphabet_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+; Uncomment to sort lists alphabetically (instead of by popularity); note that
+; this will not changed the values returned -- you will still get only the
+; <result_limit> most popular entries -- it only affects display order.
+;alphabetical_order = true
+
+; This section controls the availability of export methods.
+;
+; Each entry may be a comma-separated list of contexts in which the export
+; option will be presented. Valid options:
+;
+; bulk - Included in batch export contexts
+; record - Included in single-record export contexts
+;
+; If you simply set a field to true, only "record" mode will be enabled.
+; If you set a field to false, all export contexts will be disabled.
+;
+; Note that some options may be disabled for records that do not support them,
+; regardless of the setting chosen here.  You can edit the separate export.ini
+; file to add new export formats and change the behavior of existing ones.
+[Export]
+RefWorks = "record,bulk"
+EndNote = "record,bulk"
+EndNoteWeb = "record,bulk"
+MARC = false
+MARCXML = false
+RDF = false
+BibTeX = false
+RIS = false
+
+[BulkExport]
+; Export behavior to use when no bulkExportType setting is found in the matching
+; format section of export.ini; default is 'link' if not overridden below. See
+; export.ini for more details on available options.
+;defaultType = download
+
+;AddThis is optional. It uses the Add This tool available from www.addthis.com
+; and requires the username generated when an analytics account is registered.
+;[AddThis]
+;key = yourUsername
+
+; This section controls how item status information is presented in search results.
+[Item_Status]
+; Usually, there is only one location or call number for each item; however, when
+; multiple values are found, there are several possible behaviors:
+;     first = display the first value found, ignore the rest
+;     all   = show all of the values found, separated by commas
+;     msg   = show a message like "Multiple Call Numbers" or "Multiple Locations"
+;     group = show availability statuses for each location on a separate line,
+;             followed by callnumber information (valid for multiple_locations only)
+multiple_call_nos = first
+multiple_locations = msg
+
+; If your ILS driver supports services, VuFind will display a more detailed
+; availability message. This setting may be used to indicate that one particular
+; status is preferred over all others and should be displayed by itself when
+; found. This is useful because some drivers will always provide both "loan" and
+; "presentation" services, but most users will only care about "loan" (since in-
+; library use is implied by the ability to borrow an item). Set this to false to
+; always display all services.
+preferred_service = "loan"
+
+; Show the full location, call number, availability for each item.
+; You can customize the way each item's status is displayed by overriding the
+; ajax/status-full.phtml template.
+; When enabled, this causes the multiple_call_nos, multiple_locations and
+; preferred_service settings to be ignored.
+show_full_status = false
+
+; You can set this to the name of an alphabetic browse handler (see the
+; [AlphaBrowse_Types] section) in order to link call numbers displayed on the
+; holdings tab and in status messages to a specific browse list. Set to false
+; to disable call number linking.
+callnumber_handler = false
+
+; This section controls the behavior of the Record module.
+[Record]
+; Set this to true in order to enable "next" and "previous" links to navigate
+; through the current result set from within the record view.
+next_prev_navigation = false
+
+; Set this to true in order to enable "first" and "last" links to navigate
+; through the content result set from within the record view. Note, this
+; may cause slow behavior with some installations. The option will only work
+; when next_prev_navigation is also set to true.
+first_last_navigation = false
+
+; Setting this to true will cause VuFind to skip the results page and
+; proceed directly to the record page when a search has only one hit.
+jump_to_single_search_result = false
+
+; You can enable this setting to show links to related MARC records using certain
+; 7XX fields. Just enter a comma-separated list of the MARC fields that you wish
+; to make use of.
+;marc_links = "760,762,765,767,770,772,773,774,775,776,777,780,785,787"
+; In the marc_links_link_types enter the fields you want the module to use to
+; construct the links. The module will run through the link types in order
+; until it finds one that matches. If you don't have id numbers in the fields,
+; you can also use title to construct a title based search. id represents a raw
+; bib id, dlc represents an LCCN.  Default setting:
+;marc_links_link_types = id,oclc,dlc,isbn,issn,title
+; Set use_visibility_indicator to false if you want to show links that are marked as
+; "Do not show" in the MARC record (indicator 1). Otherwise, these links will be
+; suppressed. (Default = true)
+;marc_links_use_visibility_indicator = false
+
+; When displaying publication information from 260/264, this separator will be
+; placed between repeating subfield values (default is to rely on existing ISBD
+; punctuation, but this can be used when ISBD punctuation is absent (e.g. ", ").
+;marcPublicationInfoSeparator = " "
+
+; When displaying publication information from 260/264, this can be set to true
+; to make 264 information completely replace 260 information. Default is false,
+; which will display information from 260 AND 264 when both fields are populated.
+; Note that this only affects display, not indexing; both fields will always be
+; made searchable.
+;replaceMarc260 = false
+
+; Set the URI-pattern of the server which serves the raw Marc-data. (see
+; https://vufind.org/wiki/configuration:remote_marc_records for more information
+; on how to set up a remote service for raw Marc-data)
+;remote_marc_url = http://127.0.0.1/%s
+
+; You can use this setting to hide holdings information for particular named locations
+; as returned by the catalog.
+hide_holdings[] = "World Wide Web"
+
+; This array controls which Related modules are used to display sidebars on the
+; record view page.
+;
+; Available options:
+;    Channels - Display links to channels of content related to record
+;    Similar - Similarity based on Solr lookup
+;    WorldCatSimilar - Similarity based on WorldCat lookup
+related[] = "Similar"
+
+; This setting controls which citations are available; set to true for all supported
+; options (default); set to false to disable citations; set to a comma-separated list
+; to activate only selected formats (available options: APA, Chicago, MLA). The
+; comma-separated list option may also be used to customize citation display order.
+;citation_formats = APA,Chicago,MLA
+
+; The following two sections control the Alphabetic Browse module.
+[AlphaBrowse]
+; This setting controls how many headings are displayed on each page of results:
+page_size = 20
+; How many headings to show before the match (or the spot where the match
+; would have been found). Default is 0 for backwards compatibility.
+rows_before = 0
+; highlight the match row (or spot where match would have been)? default false
+highlighting = false
+; SEE ALSO: the General/includeAlphaBrowse setting in searchbox.ini, for including
+; alphabrowse options in the main search drop-down options.
+
+; This section controls the order and content of the browse type menu in the
+; Alphabetic Browse module.  The key is the browse index to use, the value is the
+; string to display to the user (subject to translation).
+[AlphaBrowse_Types]
+topic = "By Topic"
+author = "By Author"
+title = "By Title"
+lcc = "By Call Number"
+;dewey = "By Call Number"
+
+; This section controls the return of extra columns for the different browses.
+; The key is the browse index, the value is a colon-separated string of extra
+; Solr fields to return for display to the user.
+; Values should be in translation file as browse_value.
+[AlphaBrowse_Extras]
+title = "author:format:publishDate"
+lcc = title
+dewey = title
+
+; This section allows you to configure the values used for Cryptography; the
+; HMACkey can be set to any value you like and should never be shared.  It is used
+; to prevent users from tampering with certain URLs (for example, "place hold" form
+; submissions)
+[Security]
+HMACkey = mySuperSecretValue
+
+; This section sets global defaults for caches; file caching is used by default.
+; A custom directory for caching can be defined by the environment variable
+; VUFIND_CACHE_DIR (see httpd-vufind.conf). The default location is inside the
+; local settings directory.
+[Cache]
+; Set time to live value for Zend caches (in seconds), 0 means maximum possible.
+;ttl = 0
+; Override umask for cache directories and files.
+;umask = 022
+; Permissions for Zend-created cache directories and files, subject to umask
+; Default dir_permission seems to be 0700.
+;dir_permission = 0700
+; Default file_permission seems to be 0600.
+;file_permission = 0600
+
+; This section controls the "Collections" module -- the special view for records
+; that represent collections, and the mechanism for browsing these records.
+[Collections]
+; Control whether or not the collections module is enabled in search results.
+; If set to true any search results which are collection level items will
+; link to the respective collections page rather than the record page
+; (default = false).
+;collections = true
+; Control default tab of Collection view (default = CollectionList); see also
+; CollectionTabs.ini.
+;defaultTab = CollectionList
+; This controls where data is retrieved from to build the Collections/Home page.
+; It can be set to Index (use the Solr index) or Alphabetic (use the AlphaBrowse
+; index). Index is subject to "out of memory" errors if you have many (150000+)
+; collections; Alphabetic has no memory restrictions but requires generation of
+; a browse index using the index-alphabetic-browse tool.  (default = Index)
+;browseType = Index
+; This string is the delimiter used between title and ID in the hierarchy_browse
+; field of the Solr index.  Default is "{{{_ID_}}}" but any string may be used;
+; be sure the value is consistent between this configuration and your indexing
+; routines.
+;browseDelimiter = "{{{_ID_}}}"
+; This controls the page size within the Collections/Home page (default = 20).
+;browseLimit = 20
+; List of record routes that are converted to collection routes (used to map
+; route names when a record identifies itself as a collection and the collections
+; setting above is true).
+route[record] = collection
+route[search2record] = search2collection
+
+; This section addresses hierarchical records in the Solr index
+[Hierarchy]
+; Name of hierarchy driver to use if no value is specified in the hierarchytype
+; field of the Solr index.
+driver = Default
+; Should we display hierarchy trees? (default = false)
+;showTree = true
+; "Search within trees" can be disabled here if set to "false" (default = true)
+search = true
+; You can limit the number of search results highlighted when searching the tree;
+; a limit is recommended if you have large trees, as otherwise large numbers of
+; results can cause performance problems.  If treeSearchLimit is -1 or not set,
+; results will be unlimited.
+treeSearchLimit = 100
+; Whether hierarchy fields are used for linking between container records and their
+; children (default = false). This is an alternative to the full collections support
+; (see the [Collections] section), so only one of them should be enabled
+; at a time e.g. unless custom record drivers are used. When using this setting,
+; you may also wish to enable the ComponentParts tab in RecordTabs.ini.
+;simpleContainerLinks = true
+
+; This section will be used to configure the feedback module.
+; Set "tab_enabled" to true in order to enable the feedback module.
+; Forms are configured in FeedbackForms.yaml
+[Feedback]
+;tab_enabled       = true
+
+; Default values for form recipient and email subject, if not overridden for a
+; specific form in FeedbackForms.yaml
+;recipient_email   = "feedback@myuniversity.edu"
+;recipient_name    = "Your Library"
+;email_subject     = "VuFind Feedback"
+
+; This is the information for where feedback emails are sent from.
+;sender_email      = "noreply@vufind.org"
+;sender_name       = "VuFind Feedback"
+
+; Note: for additional details about stats (including additional notes on Google
+; Analytics and Piwik), look at the wiki page:
+;     https://vufind.org/wiki/configuration:usage_stats
+
+; Uncomment this section and provide your API key to enable Google Analytics. Be
+; sure to set the "universal" setting to true once your account is upgraded to
+; Universal Analytics; see:
+; https://developers.google.com/analytics/devguides/collection/upgrade/guide
+;[GoogleAnalytics]
+;apiKey = "mykey"
+;universal = false
+
+; Uncomment this section and provide your Piwik server address and site id to
+; enable Piwik analytics. Note: VuFind's Piwik integration uses several custom
+; variables; to take advantage of them, you must reconfigure Piwik by switching
+; to its root directory and running this command to raise a default limit:
+; ./console customvariables:set-max-custom-variables 10
+[Piwik]
+;url = "http://server.address/piwik/"
+;site_id = 1
+; Uncomment the following setting to track additional information about searches
+; and displayed records with Piwik's custom variables
+;custom_variables = true
+; By default, Piwik searches are tracked using the format "Backend|Search Terms."
+; If you need to differentiate searches coming from multiple VuFind instances using
+; a shared site_id, you can set the searchPrefix to add an additional prefix to
+; the string, for example "SiteA|Backend|Search Terms." Most users will want to
+; leave this disabled.
+;searchPrefix = "SiteA|"
+; Uncomment the following setting to disable cookies for privacy reasons.
+; see https://matomo.org/faq/general/faq_157/ for more information.
+;disableCookies = true
+
+; Uncomment portions of this section to activate tabs in the search box for switching
+; between search modules. Keys are search backend names, values are labels for use in
+; the user interface (subject to translation). If you need multiple tabs for a single
+; backend, append a colon and a suffix to each backend name (e.g. Solr:main) and add
+; the filters in the [SearchTabsFilters] section.
+[SearchTabs]
+;Solr = Catalog
+;Summon = Summon
+;WorldCat = WorldCat
+;Solr:filtered = "Catalog (Main Building Books)"
+;EDS = "EBSCO Discovery Service"
+;EIT = "EBSCO Integration Toolkit"
+;Primo = "Primo Central"
+
+; Add any hidden filters in this section for search tab specific filtering
+[SearchTabsFilters]
+;Solr:filtered[] = 'building:"main library"'
+;Solr:filtered[] = "format:book"
+
+; You can bind a permission to a search tab in this section.
+; This controls to whom the tab should be displayed.
+; Use the format tabName = permission. The permission should be configured
+; in permissions.ini (who should see the tab)
+; and permissionBehavior.ini (what should be displayed instead of the tab).
+; Note that this ONLY controls whether or not the tab is displayed; if you wish to
+; restrict actual searching, you will also need to make sure that the relevant
+; controller(s) are blocking access using the same named permission.
+[SearchTabsPermissions]
+;EIT = access.EITModule
+;Primo = access.PrimoModule
+
+; Uncomment portions of this section to label searches from particular sources in the
+; search history display.  Keys are search backend names, values are labels for use in
+; the user interface (subject to translation).
+[SearchHistoryLabels]
+;Solr = Catalog
+;Summon = Summon
+;WorldCat = WorldCat
+;SolrWeb = "Library Website"
+;EDS = "EBSCO Discovery Service"
+
+; Activate Captcha validation on select forms
+; VuFind will use reCaptcha validation to prevent bots from using certain actions of
+; your instance. See http://www.google.com/recaptcha for more information on Captcha
+; and create keys for your domain.
+; You will need to provide a sslcapath in the [Http] section for your Captcha to work.
+;[Captcha]
+;siteKey  = "get your reCaptcha key at"
+;secretKey = "https://www.google.com/recaptcha/admin/create"
+; Valid theme values: dark, light
+;theme      = light
+; Valid forms values: changePassword, email, feedback, newAccount, passwordRecovery,
+;                     sms, userComments
+; Use * for all supported forms
+; Note: when "feedback" is active, Captcha can be conditionally disabled on a
+;       form-by-form basis with the useCaptcha setting in FeedbackForms.yaml.
+;forms = changeEmail, changePassword, email, newAccount, passwordRecovery, sms
+
+
+; This section can be used to display default text inside the search boxes, useful
+; for instructions. Format:
+;
+; backend = Placeholder text
+;
+; You can use a "default" setting if you want a standard string displayed across
+; all backends not otherwise specified. You can qualify backend names with a
+; colon-delimited suffix if you wish to use special placeholders in combination
+; with filtered search tabs (see [SearchTabsFilters] above).
+[SearchPlaceholder]
+;default = "Enter search terms here..."
+;Solr = "Search the catalog"
+;Solr:filtered = "Search the filtered catalog"
+;Summon = "Search Summon"
+
+; This section controls VuFind's social features.
+[Social]
+; Comments may be "enabled" or "disabled" (default = "enabled")
+comments = enabled
+; Favorite lists may be "enabled", "disabled", "public_only" or "private_only"
+; (default = "enabled")
+; The public_only/private_only settings restrict the type of list users may
+; create. If you change this to a more restrictive option, it is your responsibility
+; to update the user_list database table to update the status of existing lists.
+lists = enabled
+; The following two settings are equivalent to default_limit / limit_options in
+; searches.ini, but used to control the page sizes of lists of favorites:
+lists_default_limit   = 20
+;lists_limit_options   = 10,20,40,60,80,100
+; This section controls what happens when a record title in a favorites list
+; is clicked. VuFind can either embed the full result directly in the list using
+; AJAX or can display it at its own separate URL as a full HTML page.
+; See the [List] section of searches.ini for all available options.
+lists_view=full
+; Tags may be "enabled" or "disabled" (default = "enabled")
+; When disabling tags, don't forget to also turn off tag search in searches.ini.
+tags = enabled
+; This controls the maximum length of a single tag; it should correspond with the
+; field size in the tags database table.
+max_tag_length = 64
+; This controls whether tags are case-sensitive (true) or always forced to be
+; represented as lowercase strings (false -- the default).
+case_sensitive_tags = false
+; If this setting is set to false, users will not be presented with a search
+; drop-down or advanced search link when searching/viewing tags. This is recommended
+; when using a multi-backend system (e.g. Solr + Summon + WorldCat). If set to
+; true, the standard Solr search options and advanced search link will be shown
+; in the tag screens; this is recommended when using a Solr-only configuration.
+show_solr_options_in_tag_search = false
diff --git a/module/VuFind/tests/fixtures/configs/amazonreview/config.ini b/module/VuFind/tests/fixtures/configs/amazonreview/config.ini
new file mode 100644
index 00000000000..244aacb1f34
--- /dev/null
+++ b/module/VuFind/tests/fixtures/configs/amazonreview/config.ini
@@ -0,0 +1,1896 @@
+;
+; VuFind Configuration
+;
+
+; This section controls global system behavior and can usually be left unmodified.
+[System]
+; Change to false to take the system offline and show an unavailability message;
+; note that you can use the NoILS driver (in [Catalog] section below) to keep VuFind
+; up during ILS maintenance.
+available       = true
+; Change to true to see messages about the behavior of the system as part of the
+; output -- only for use when troubleshooting problems. See also the access.DebugMode
+; setting in permissions.ini to turn on debug using a GET parameter in the request.
+debug           = false
+; This setting should be set to false after auto-configuration is complete
+autoConfigure = true
+; This setting specifies a health check file location. If a health check file exists,
+; the getServerStatus AJAX call will return an error regardless of actual status
+; allowing the server to be disabled from a load-balancer.
+;healthCheckFile = /tmp/disable_vufind
+
+; This section will need to be customized for your installation
+[Site]
+; Base URL is normally auto-detected, but this setting is used when autodetection is
+; not possible (i.e. during sitemap generation at the command line).
+url             = http://library.myuniversity.edu/vufind
+; Set to true if VuFind is behind a reverse proxy (typically Apache with mod_proxy),
+; make sure your reverse proxy sets the necessary headers.
+;reverse_proxy    = true
+email           = support@myuniversity.edu
+title           = "Library Catalog"
+; This is the default theme for non-mobile devices (or all devices if mobile_theme
+; is disabled below). Available standard themes:
+;   bootstrap3 = HTML5 theme using Bootstrap 3 + jQuery libraries, with minimal styling
+;   bootprint3 = bootstrap3 theme with more attractive default styling applied
+;                (named after the earlier, now-deprecated blueprint theme)
+;   sandal     = bootstrap3 theme with a "flat" styling applied (a newer look
+;                than bootprint3).
+theme           = bootprint3
+
+; Uncomment the following line to use a different default theme for mobile devices.
+; You may not wish to use this setting if you are using one of the Bootstrap-based
+; standard themes since they support responsive design.
+;mobile_theme    = mobile
+
+; Automatic asset minification and concatenation setting. When active, HeadScript
+; and HeadLink will concatenate and minify all viable files to reduce requests and
+; load times. This setting is off by default.
+;
+; This configuration takes the form of a semi-colon separated list of
+; environment:configuration pairs where "environment" is a possible APPLICATION_ENV
+; value (e.g. 'production' or 'development') or '*'/no prefix for all contexts.
+; Possible values for 'configuration' within each environment are 'js', 'css',
+; 'off'/false, 'on'/true/'*'. This allows global enabling/disabling of the pipeline
+; or separate configurations for different types of resources. Multiple configuration
+; values may be comma-separated -- e.g. 'js,css'.
+;
+; Example: "development:off; production:js,css"
+;asset_pipeline = "production:js"
+
+; This is a comma-separated list of themes that may be accessed via the ?ui GET
+; parameter.  Each entry has two parts: the value used on the URL followed by the
+; actual theme name.  For example, http://library.myuniversity.edu/vufind?ui=theme1
+; would load the myTheme1 theme with the setting shown below.  Note that the values
+; of "standard" and "mobile" are reserved for the default and mobile themes defined
+; above.
+;alternate_themes = theme1:myTheme1,theme2:myTheme2
+
+; This is a comma-separated list of theme options that will be displayed to the user
+; as a drop-down.  Each entry has two parts: a value for the "ui" GET parameter and
+; an on-screen description.  "standard" refers to the "theme" setting above, "mobile"
+; refers to the "mobile_theme" setting, and all other values must be defined in
+; alternate_themes above.  When commented out, no drop-down theme list will display.
+;selectable_themes = "standard:Standard Theme,mobile:Mobile Theme"
+
+; Use the browser language setting to set the VuFind language.
+browserDetectLanguage = true
+language        = en    ; default -- more options available in [Languages] below.
+locale          = en_US
+; Set this to specify a default ISO 4217 currency code (used on the fines screen).
+; If omitted, the default currency for the locale above will be used.
+;defaultCurrency = USD
+; Find valid timezone values here:
+;   http://www.php.net/manual/en/timezones.php
+timezone        = "America/New_York"
+; A string used to format user interface date strings using the PHP date() function
+; default is m-d-Y (MM-DD-YYYY 01-01-2010)
+displayDateFormat = "m-d-Y"
+; A string used to format user interface time strings using the PHP date() function
+; default is H:i (HH:MM 23:01)
+displayTimeFormat = "H:i"
+; The base VuFind URL will load this controller unless the user is logged in:
+defaultModule   = Search
+; When defaultModule is used, this action will be triggered (default = Home)
+;defaultAction = Home
+; The base VuFind URL will load this controller when the user is logged in:
+defaultLoggedInModule = MyResearch
+; When defaultLoggedInModule is used, this action will be triggered (default = Home)
+;defaultLoggedInAction = Home
+; The search backend that VuFind will use in search boxes when nothing else is
+; specified (e.g. on user account pages, search history, etc.). Default = Solr
+;defaultSearchBackend = Solr
+; The route VuFind will send users to following a log out operation. Set to false
+; or omit to attempt to retain the user's current context after log out.
+;logOutRoute = home
+; Default tab to display when a record is viewed (see also RecordTabs.ini):
+defaultRecordTab = Holdings
+; Hide the holdings tab if no holdings are available from the ILS; note that this
+; feature requires your ILS driver to support the hasHoldings() method.
+hideHoldingsTabWhenEmpty = false
+; Whether to load the default tab through AJAX (which brings some performance
+; gain but breaks compatibility with non-Javascript-enabled browsers; off by default)
+;loadInitialTabWithAjax = true
+; The holdingsTemplate to use to display the ILS holdings (defaults to standard).
+; See the templates/RecordTab/holdingsils subdirectory of your theme for options.
+;holdingsTemplate = extended
+; This page will show by default when a user accesses the MyResearch module:
+defaultAccountPage = Favorites
+; Allow access to the Admin module? (See the access.AdminModule setting in
+; permissions.ini for more granular ways to restrict Admin access).
+admin_enabled = false
+; Show sidebar on the left side instead of right
+sidebarOnLeft = false
+; Invert the sidebarOnLeft setting for right-to-left languages?
+mirrorSidebarInRTL = true
+; Put search result thumbnails on the left (true) or right (false)
+resultThumbnailsOnLeft = true
+; Put favorites list thumbnails on the left (true) or right (false)
+listThumbnailsOnLeft = true
+; Put hold/checkedout/ILL/etc. item thumbnails on the left (true) or right (false)
+accountThumbnailsOnLeft = true
+; Show thumbnail on opposite side in right-to-left languages?
+mirrorThumbnailsRTL = true
+; Handle menu as an offcanvas slider at mobile sizes (in bootstrap3-based themes)
+offcanvas = false
+; Show (true) / Hide (false) Book Bag - Default is Hide.
+showBookBag = false
+; Set the maximum amount of items allowed in the Book Bag - Default is 100
+bookBagMaxSize = 100
+; Show individual add/remove bookbag buttons in search results? (Supersedes cart
+; checkboxes and bulk action buttons unless showBulkOptions is true).
+bookbagTogglesInSearch = true
+; Display bulk items (export, save, etc.) and checkboxes on search result screens?
+showBulkOptions = false
+; Should users be allowed to save searches in their accounts?
+allowSavedSearches = true
+; Some VuFind features can be made compatible with non-Javascript browsers at
+; a performance cost. By default, this compatibility is disabled, but it can
+; be turned on here. Note that even with this setting turned on, some features
+; still require Javascript; this simply improves compatibility for certain
+; features (such as display of hierarchies).
+nonJavascriptSupportEnabled = false
+; Generator value to display in an HTML header <meta> tag:
+generator = "VuFind 6.1.1"
+
+; This section allows you to configure the mechanism used for storing user
+; sessions.  Available types: File, Memcache, Database, Redis.
+; Some of the settings below only apply to specific session handlers;
+; such settings are named with an obvious prefix.  Non-prefixed settings
+; are global to all handlers.
+[Session]
+type                        = File
+lifetime                    = 3600 ; Session lasts for 1 hour
+; Should stored session data be encrypted?
+secure = false
+; Keep-alive interval in seconds. When set to a positive value, the session is kept
+; alive with a JavaScript call as long as a VuFind page is open in the browser.
+; Default is 0 (disabled). When keep-alive is enabled, session lifetime above can be
+; reduced to e.g. 600.
+;keepAlive = 60
+;file_save_path              = /tmp/vufind_sessions
+;memcache_host               = localhost
+;memcache_port               = 11211
+;memcache_connection_timeout = 1
+;
+; Settings related to Redis-based sessions; default values are listed below
+;redis_host               = localhost
+;redis_port               = 6379
+;redis_connection_timeout = 0.5
+;redis_db                 = 0
+;redis_auth               = some_secret_password
+;redis_version            = 3
+;redis_standalone         = true
+
+; This section controls how VuFind creates cookies (to store session IDs, bookbag
+; contents, theme/language settings, etc.)
+[Cookies]
+; In case there are multiple VuFind instances on the same server and they should not
+; share cookies/sessions, this option can be enabled to limit the session to the
+; current path. Default is false, which will place cookies at the root directory.
+;limit_by_path = true
+; If VuFind is only accessed via HTTPS, this setting can be enabled to disallow
+; the browser from ever sending cookies over an unencrypted connection (i.e.
+; before being redirected to HTTPS). Default is false.
+;only_secure = true
+; Whether to set cookies set by the server (apart from cart function) "HTTP only" so
+; that they cannot be accessed by scripts. Default is true.
+;http_only = false
+; Set the domain used for cookies (sometimes useful for sharing the cookies across
+; subdomains); by default, cookies will be restricted to the current hostname.
+;domain = ".example.edu"
+; This sets the session cookie's name. Comment this out to use the default
+; PHP_SESS_ID value. If running multiple versions of VuFind (or multiple PHP
+; applications) on the same host, it is strongly recommended to give each a
+; different session_name setting to avoid data contamination.
+session_name = VUFIND_SESSION
+
+; Please set the ILS that VuFind will interact with.
+;
+; Available drivers:
+;   - Aleph
+;   - Alma
+;   - Amicus
+;   - DAIA (using either XML or JSON API)
+;   - Demo (fake ILS driver returning complex responses)
+;   - Evergreen
+;   - Folio
+;   - Horizon (basic database access only)
+;   - HorizonXMLAPI (more features via API)
+;   - Innovative (for INNOPAC; see also Sierra/SierraRest)
+;   - Koha (basic database access only)
+;   - KohaILSDI (more features via ILS-DI API)
+;   - LBS4
+;   - MultiBackend (to chain together multiple drivers in a consortial setting)
+;   - NewGenLib
+;   - NoILS (for users with no ILS, or to disable ILS features during maintenance),
+;   - PAIA
+;   - Polaris
+;   - Sample (fake ILS driver returning bare-minimum data)
+;   - Sierra (basic database access only)
+;   - SierraRest (more features via API)
+;   - Symphony (uses native SirsiDynix APIs)
+;   - Unicorn (also applies to Symphony; requires installation of connector found at:
+;     http://code.google.com/p/vufind-unicorn/)
+;   - Virtua
+;   - Voyager (database access only; for Voyager 6+)
+;   - VoyagerRestful (for Voyager 7+ w/ RESTful web services)
+;   - XCNCIP2 (for XC NCIP Tookit v2.x)
+;
+; If you haven't set up your ILS yet, two fake drivers are available for testing
+; purposes. "Sample" is fast but does very little; "Demo" simulates more
+; functionality of a real ILS but may slow down your system by performing extra
+; searches. If you don't plan to use an ILS, the NoILS driver is your best option.
+;
+; Note: Enabling most of the features in this section will only work if you use an
+; ILS driver that supports them; not all drivers support holds/renewals.
+[Catalog]
+driver          = Sample
+
+; loadNoILSOnFailure - Whether or not to load the NoILS driver if the main driver fails
+loadNoILSOnFailure = false
+
+; List of search backends that contain records from your ILS (defaults to Solr
+; unless set otherwise). You can set ilsBackends = false to disable ILS status
+; loading entirely.
+;ilsBackends[] = Solr
+
+; This setting determines how and when hold / recall links are displayed.
+; Legal values:
+; - all (Show links for all items - Place Hold for Available Items and Place Recall
+;   for unavailable items)
+; - availability (Only show recall links if ALL items on bib are currently
+;   unavailable)
+; - disabled (Never show hold/recall links)
+; - driver (Use ILS driver to determine which items may be held/recalled; best option
+;   if available, but not supported by all drivers)
+; - holds (Only show links for available items)
+; - recalls (Only show links for unavailable items)
+; default is "all"
+holds_mode = "all"
+
+; Set this to true if you want to allow your ILS driver to override your holds_mode
+; setting on a record-by-record basis; this may be useful for local customizations,
+; but in most cases you should leave this setting unchanged.  Overrides are ignored
+; for mode settings of "driver" or "disabled."
+allow_holds_override = false
+
+; Determines if holds can be cancelled or not. Options are true or false.
+; default is false
+cancel_holds_enabled = false
+
+; Determines if storage retrieval requests can be cancelled or not.
+; Options are true or false.
+; default is false
+cancel_storage_retrieval_requests_enabled = false
+
+; Determines if ILL requests can be cancelled or not.
+; Options are true or false.
+; default is false
+cancel_ill_requests_enabled = false
+
+; Determines if item can be renewed or not. Options are true or false.
+; default is false
+renewals_enabled = false
+
+; Determines if title level holds are displayed or not.
+; Legal values:
+; - disabled (Never show title Holds - Default)
+; - always (Always show title Holds)
+; - availability (Only show title holds if ALL items on bib are currently
+;   unavailable)
+; - driver (Use ILS driver to determine which items may be held/recalled; best option
+;   if available, but not supported by all drivers)
+title_level_holds_mode = "disabled"
+
+; Determines how holdings are grouped in the record display, using fields from
+; the item information provided by the ILS driver.
+;
+; Most commonly-used values:
+; - holdings_id,location (Use holdings record id if available, location name as
+;   secondary - Default)
+; - location (Use location name)
+;
+; See https://vufind.org/wiki/development:plugins:ils_drivers#getholding for
+; more options (though not every ILS driver supports every possible value).
+;
+; Note that there may also be driver-specific values outside of the specification,
+; such as:
+; - item_agency_id (XCNCIP2 driver's Agency ID, which may be useful in consortial
+;   environments)
+;
+; You may use multiple group keys (delimited by comma), e.g.,
+; - item_agency_id,location
+;holdings_grouping = holdings_id,location
+
+; Text fields such as holdings_notes gathered from items to be displayed in each
+; holdings group in the display order.
+; The default list is 'holdings_notes', 'summary', 'supplements' and 'indexes'. The
+; deprecated field 'notes' is used as an alias for 'holdings_notes'.
+; Note that displayed information depends on what the ILS driver returns.
+;holdings_text_fields[] = 'holdings_notes'
+;holdings_text_fields[] = 'summary'
+
+; Whether support for multiple library cards is enabled. Default is false.
+;library_cards = true
+
+; The number of checked out items to display per page; 0 for no limit (may cause
+; memory problems for users with huge numbers of items). Default = 50.
+;checked_out_page_size = 50
+
+; The number of historic loans to display per page; 0 for no limit (may cause
+; memory problems for users with a large number of historic loans). Default = 50
+;historic_loan_page_size = 50
+
+; Whether to display the item barcode for each loan. Default is false.
+;display_checked_out_item_barcode = true
+
+; This section controls features related to user accounts
+[Account]
+; Allow the user to set a home library through the Profile screen, which will
+; override ILS-provided default pickup locations throughout the system.
+set_home_library = true
+
+; Allow the user to "subscribe" to search history entries in order to receive
+; email notifications of new search results.
+schedule_searches = false
+
+; Should we always send a scheduled search email the first time we run notices
+; after a user has subscribed (true), or should we only send an email when there
+; is actually something new (false, default)
+force_first_scheduled_email = false
+
+; When schedule_searches is set to true, you can customize the schedule frequencies
+; here -- just use the number of days between notifications in the brackets. Labels
+; will be run through the translator.
+;scheduled_search_frequencies[0] = schedule_none
+;scheduled_search_frequencies[1] = schedule_daily
+;scheduled_search_frequencies[7] = schedule_weekly
+
+; This section allows you to determine how the users will authenticate.
+; You can use an LDAP directory, the local ILS (or multiple ILSes through
+; the MultiILS option), the VuFind database (Database), a hard-coded list of
+; access passwords (PasswordAccess), AlmaDatabase (combination
+; of VuFind database and Alma account), Shibboleth, SIP2, CAS, Facebook, Email or
+; some combination of these (via the MultiAuth or ChoiceAuth options).
+;
+; The Email method is special; it is intended to be used through ChoiceAuth in
+; combination with Database authentication (or any other method that reliably stores
+; the user's email address) to make it possible to log in by receiving an
+; authentication link at the email address stored in VuFind's database. Email is
+; also supported as the primary authentication mechanism for some ILS drivers (e.g.
+; Alma). In these cases, ChoiceAuth is not needed, and ILS should be configured as
+; the Authentication method; see the ILS driver's configuration for possible options.
+;
+; Also note that the Email method stores hashes in your database's auth_hash table.
+; You should run the "php $VUFIND_HOME/public/index.php util expire_auth_hashes"
+; utility periodically to clean out old data in this table.
+[Authentication]
+;method          = LDAP
+;method         = ILS
+method         = Database
+;method         = AlmaDatabase
+;method         = Shibboleth
+;method         = SIP2
+;method         = CAS
+;method         = MultiAuth
+;method         = ChoiceAuth
+;method         = MultiILS
+;method         = Facebook
+;method         = PasswordAccess
+;method         = Email
+
+; This setting only applies when method is set to ILS.  It determines which
+; field of the ILS driver's patronLogin() return array is used as the username
+; in VuFind's user database.  If commented out, it defaults to cat_username
+; (the recommended setting in most situations).
+;ILS_username_field = cat_username
+
+; Whether or not to hide the Login Options; not that even when this is set to
+; false, ILS driver settings may be used to conditionally hide the login. See
+; hideLogin in the [Settings] section of NoILS.ini for an example.
+hideLogin = false
+
+; When set to true, uses AJAX calls to annotate the account menu with
+; notifications (overdue items, total fines, etc.)
+enableAjax = true
+
+; When set to true, replicates the account menu as a drop-down next to the
+; account link in the header.
+enableDropdown = false
+
+; Set this to false if you would like to store local passwords in plain text
+; (only applies when method = Database or AlmaDatabase above).
+hash_passwords = false
+
+; Allow users to recover passwords via email (if supported by Auth method)
+; You can set the subject of recovery emails in your
+; language files under the term "recovery_email_subject"
+recover_password = false
+; Time (seconds) before another recovery attempt can be made
+recover_interval      = 60
+; Length of time before a recovery hash can no longer be used (expires)
+; Default: Two weeks
+recover_hash_lifetime = 1209600
+
+; Allow users to set change their email address (if supported by Auth method).
+; When turning this on, it is also strongly recommended to turn on verify_email
+; below.
+change_email = false
+
+; Allow users to set change their passwords (if supported by Auth method)
+change_password = true
+
+; Force users to verify their email address before being able to log in
+; (only if method=Database) or make changes to it (if change_email=true).
+; If you wish to customize the email messages used by the system, see the
+; translation strings starting with verify and change_notification, as well as
+; the notify-email-change.phtml and verify-email.phtml Email templates.
+verify_email = false
+
+; Set this to false if you would like to store catalog passwords in plain text
+encrypt_ils_password = false
+
+; This is the key used to encrypt and decrypt catalog passwords.  This must be
+; filled in with a random string value when encrypt_ils_passwords is set to true.
+ils_encryption_key = false
+
+; This is the algorithm used to encrypt and decrypt catalog passwords.
+; A symmetrical encryption algorithm must be used.
+; You can use openssl_get_cipher_methods() to see available options on your system.
+; Common choices: blowfish (default), aes
+; If you want to convert from one algorithm to another, run this from $VUFIND_HOME:
+;   php public/index.php util switch_db_hash oldhash:oldkey (or none) newhash:newkey
+;ils_encryption_algo = "blowfish"
+
+; This setting may optionally be uncommented to restrict the email domain(s) from
+; which users are allowed to register when using the Database or AlmaDatabase method.
+;domain_whitelist[] = "myuniversity.edu"
+;domain_whitelist[] = "mail.myuniversity.edu"
+
+; Specify default minimum and maximum password length (Auth method may override
+; this).
+;minimum_password_length = 4
+;maximum_password_length = 32
+; Specify default limit of accepted characters in the password. Allowed values
+; are "numeric", "alphanumeric" or a regular expression
+;password_pattern = "(?=.*\d)(?=.*[a-z])(?=.*[A-Z])"
+; Specify default hint about what the password may contain when using a regexp
+; pattern. May be text or a translation key. The "numeric" and "alphanumeric"
+; patterns have translated default hints.
+;password_hint = "Include both upper and lowercase letters and at least one number."
+
+; Uncomment this line to switch on "privacy mode" in which no user information
+; will be stored in the database. Note that this is incompatible with social
+; features, password resets, and many other features. It is not recommended for
+; use with "Database" or "AlmaDatabase" authentication, since the user will be
+; forced to create a new account upon every login.
+;privacy = true
+
+; Allow a user to delete their account. Default is false.
+;account_deletion = true
+; Whether comments added by a user are deleted when they remove their account.
+; Default is true.
+;delete_comments_with_user = false
+
+; See the comments in library/VF/Auth/MultiAuth.php for full details
+; on using multiple authentication methods.  Note that MultiAuth assumes login
+; with username and password, so some methods (i.e. Shibboleth) may not be
+; compatible.
+;[MultiAuth]
+;method_order   = ILS,LDAP
+;filters = "username:trim,password:trim"
+
+; Present two auth options on the login screen. Each choice given must also be
+; configured in its relevant section. (The code should allow for more than 2
+; choices, but styling would need to be expanded / modified)
+;
+; WARNING! This module does not account for the possibility that the auth
+; choices you present may return different usernames. You would want a user to
+; be able to log in via any method and see the same account. To make sure that
+; is the case, you should ensure that the usernames given by the authentication
+; methods themselves are the same for any given user.
+;[ChoiceAuth]
+;choice_order = Shibboleth,Database
+
+; This section defines the location/behavior of the Solr index and requires no
+; changes for most installations
+[Index]
+; url can also be an array of servers. If so, VuFind will try the servers one by one
+; until one can be reached. This is only useful for advanced fault-tolerant Solr
+; installations.
+url             = http://localhost:8080/solr
+; Default bibliographic record core
+default_core    = biblio
+; Default authority record core
+default_authority_core = authority
+; This setting needs to match the <maxBooleanClauses> setting in your solrconfig.xml
+; file; when VuFind has to look up large numbers of records using ID values, it may
+; have to restrict the size of its result set based on this limitation.
+maxBooleanClauses = 1024
+; This is the timeout in seconds when communicating with the Solr server.
+timeout = 30
+; This is the Dismax handler to use if nothing is specified in searchspecs.yaml.
+; You can choose dismax for standard Dismax (the default) or edismax for Extended
+; Dismax, or you can configure your own custom handler in solrconfig.xml.
+default_dismax_handler = dismax
+; This is the number of records to retrieve in a batch e.g. when building a record
+; hierarchy. A higher number results in fewer round-trips but may increase Solr's
+; memory usage. Default is 1000.
+;cursor_batch_size = 1000
+
+
+; Enable/Disable searching reserves using the "reserves" Solr core.  When enabling
+; this feature, you need to run the util/index_reserves.php script to populate the
+; new index.
+[Reserves]
+search_enabled  = false
+
+; This section requires no changes for most installations; if your SMTP server
+; requires authentication, you can fill in a username and password below.
+[Mail]
+host            = localhost
+port            = 25
+;username       = user
+;password       = pass
+; The server name to report to the upstream mail server when sending mail.
+;name = vufind.myuniversity.edu
+; If a login is required you can define which protocol to use for securing the
+; connection. If no explicit protocol ('tls' or 'ssl') is configured, a protocol
+; based on the configured port is chosen (587 -> tls, 487 -> ssl).
+;secure         = tls
+; This setting enforces a limit (in seconds) on the lifetime of an SMTP
+; connection, which can be useful when sending batches of emails, since it can
+; help avoid errors caused by server timeouts. Comment out the setting to disable
+; the limit.
+connection_time_limit = 60
+; Uncomment this setting to disable outbound mail but simulate success; this
+; is useful for interface testing but should never be used in production!
+;testOnly = true
+; If set to false, users can send anonymous emails; otherwise, they must log in first
+require_login   = true
+; Should we put the logged-in user's address in the "from" field by default?
+user_email_in_from = false
+; Should we put the logged-in user's address in the "to" field by default?
+user_email_in_to = false
+; Should the user be allowed to edit email subject lines?
+user_editable_subjects = false
+; How many recipients is the user allowed to specify? (use 0 for no limit)
+maximum_recipients = 1
+; Populate the "from" field with this value if user_email_in_from is false and/or no
+; user is logged in:
+;default_from = "no-reply@myuniversity.edu"
+; Should we hide the "from" field in email forms? If no from field is visible, emails
+; will be sent based on user_email_in_from and default_from above, with the email
+; setting from the [Site] section used as a last resort.
+disable_from = false
+; From field override. Setting this allows keeping the "from" field in email forms
+; but will only use it as a reply-to address. The address defined here is used as the
+; actual "from" address.
+; Note: If a feature explicitly sets a different reply-to address (for example,
+; Feedback forms), the original from address will NOT override that reply-to value.
+;override_from = "no-reply@myuniversity.edu"
+
+; Being a special case of mail message, sending record results via SMS ("Text this")
+; may be "enabled" or "disabled" ("enabled" by default).
+; Should you choose to leave it enabled, see also sms.ini for further
+; configuration options.
+sms = enabled
+
+; Set this value to "database" to shorten links sent via email/SMS and
+; store its path in the database (default "none").
+url_shortener = none
+
+; This section needs to be changed to match your database connection information
+[Database]
+; Connection string format is [platform]://[username]:[password]@[host]:[port]/[db]
+; where:
+; [platform] = database platform (mysql, oci8 or pgsql)
+; [username] = username for connection
+; [password] = password for connection (optional)
+; [host] = host of database server
+; [port] = port of database server (optional)
+; [db] = database name
+database          = mysql://root@localhost/vufind
+
+; If your database (e.g. PostgreSQL) uses a schema, you can set it here:
+;schema = schema_name
+
+; The character set of the database -- may be latin1 or utf8; utf8 is STRONGLY
+; RECOMMENDED and is the default if no value is set here.  You may need latin1
+; for compatibility with existing VuFind 1.x installations.
+;charset = utf8
+
+; Reduce access to a set of single passwords
+; This is only used when Authentication method is PasswordAccess. See above.
+; Recommended to be used in conjunction with very restricted permissions.ini settings
+; and with most social settings disabled
+;[PasswordAccess]
+; access_user is a map of users to passwords
+; entering a correct password will login as that user
+;access_user[user] = password
+;access_user[admin] = superpassword
+
+; LDAP is optional.  This section only needs to exist if the
+; Authentication Method is set to LDAP.  When LDAP is active,
+; host, port, basedn and username are required.
+;[LDAP]
+; Prefix the host with ldaps:// to use LDAPS; omit the prefix for standard
+; LDAP with TLS.
+;host            = ldap.myuniversity.edu
+;port            = 389       ; LDAPS usually uses port 636 instead
+; By default, when you use regular LDAP (not LDAPS), VuFind uses TLS security.
+; You can set disable_tls to true to bypass TLS if your server does not support
+; it. Note that this setting is ignored if you use ldaps:// in the host setting.
+;disable_tls     = false
+;basedn          = "o=myuniversity.edu"
+;username        = uid
+; separator string for mapping multi-valued ldap-fields to a user attribute
+; if no separator is given, only the first value is mapped to the given attribute
+;separator = ';'
+; Optional settings to map fields in your LDAP schema to fields in the user table
+; in VuFind's database -- the more you fill in, the more data will be imported
+; from LDAP into VuFind:
+;firstname       = givenname
+;lastname        = sn
+;email           = mail
+;cat_username    =
+;cat_password    =
+;college         = studentcollege
+;major           = studentmajor
+; If you need to bind to LDAP with a particular account before
+; it can be searched, you can enter the necessary credentials
+; here.  If this extra security measure is not needed, leave
+; these settings commented out.
+;bind_username   = "uid=username o=myuniversity.edu"
+;bind_password   = password
+
+; SIP2 is optional.  This section only needs to exist if the
+; Authentication Method is set to SIP2.
+;[SIP2]
+;host            = ils.myuniversity.edu
+;port            = 6002
+
+; Shibboleth is optional.  This section only needs to exist if the
+; Authentication Method is set to Shibboleth. Be sure to set up authorization
+; logic in the permissions.ini file to filter users by Shibboleth attributes.
+;[Shibboleth]
+; Server param with the identity provider entityID if a Shibboleth session exists.
+; If omitted, Shib-Identity-Provider is used.
+;idpserverparam = Shib-Identity-Provider
+; Optional: Session ID parameter for SAML2 single logout support. If omitted, single
+; logout support is disabled. Note that if SLO support is enabled, Shibboleth session
+; ID's are tracked in external_session table which may need to be cleaned up with the
+; expire_session_mappings command line utility. See
+; https://vufind.org/wiki/configuration:shibboleth for more information on how
+; to configure the single logout support.
+;session_id = Shib-Session-ID
+; Optional: you may set attribute names and values to be used as a filter;
+; users will only be logged into VuFind if they match these filters.
+;userattribute_1       = entitlement
+;userattribute_value_1 = urn:mace:dir:entitlement:common-lib-terms
+;userattribute_2       = unscoped-affiliation
+;userattribute_value_2 = member
+; Required: the attribute Shibboleth uses to uniquely identify users.
+;username              = persistent-id
+; Required: Shibboleth login URL.
+;login                 = https://shib.myuniversity.edu/Shibboleth.sso/Login
+; Optional: Shibboleth logout URL.
+;logout                = https://shib.myuniversity.edu/Shibboleth.sso/Logout
+; Optional: URL to forward to after Shibboleth login (if omitted,
+; defaultLoggedInModule from [Site] section will be used).
+;target                = https://shib.myuniversity.edu/vufind/MyResearch/Home
+; Optional: provider_id (entityId) parameter to pass along to Shibboleth login.
+;provider_id           = https://idp.example.edu/shibboleth-idp
+; Some or all of the following entries may be uncommented to map Shibboleth
+; attributes to user database columns:
+;cat_username = HTTP_ALEPH_ID
+;cat_password = HTTP_CAT_PASSWORD
+;email = HTTP_MAIL
+;firstname = HTTP_FIRST_NAME
+;lastname = HTTP_LAST_NAME
+;college = HTTP_COLLEGE
+;major = HTTP_MAJOR
+;home_library = HTTP_HOME_LIBRARY
+
+; CAS is optional.  This section only needs to exist if the
+; Authentication Method is set to CAS.
+;[CAS]
+
+; Optional: the attribute CAS uses to uniquely identify users. (Omit to use
+; native CAS username instead of an attribute-based value).
+;username              = uid
+
+; Required: CAS Hostname.
+;server                = cas.myuniversity.edu
+
+; Required: CAS port.
+;port                 = 443
+
+; Required: CAS context.
+;context                 = /cas
+
+; Required: CAS Certificate Path. (Set to false to bypass authentication;
+; BYPASSING AUTHENTICATION IS *NOT* RECOMMENDED IN PRODUCTION).
+;CACert = /etc/pki/cert/cert.crt
+
+; Required: CAS login URL.
+;login                 = https://cas.myuniversity.edu/cas/login
+
+; Required: CAS logout URL.
+;logout                = https://cas.myuniversity.edu/cas/logout
+
+; Optional: CAS logging.
+;debug              = false
+;log                = /tmp/casdebug
+
+; Optional: URL to forward to after CAS login (if omitted,
+; defaultLoggedInModule from [Site] section will be used).
+;target                = http://lib.myuniversity.edu/vufind/MyResearch/Home
+
+; Optional: protocol to follow (legal values include CAS_VERSION_1_0,
+; CAS_VERSION_2_0, CAS_VERSION_3_0 and SAML_VERSION_1_1; default is
+; SAML_VERSION_1_1)
+;protocol = SAML_VERSION_1_1
+
+; Some or all of the following entries may be uncommented to map CAS
+; attributes to user database columns:
+;cat_username = acctSyncUserID
+;cat_password = catPassword
+;email = mail
+;firstname = givenName
+;lastname = sn
+;college = college
+;major = major1
+;home_library = library
+
+; Facebook may be used for authentication; fill in this section in addition to
+; turning it on in [Authentication] above to use it. You must register your
+; VuFind instance as an application at http://developers.facebook.com to obtain
+; credentials.
+;[Facebook]
+;appId = "your app ID"
+;secret = "your app secret"
+
+; External Content is Optional.
+; To use multiple, separate with a comma.  Priority will be given by the order listed
+; Account id is separated with a colon, if no id is used then no colon is necessary
+; For Amazon, use your 20-character access key in the coverimages and reviews values;
+; you must also provide your 40-character secret key in the amazonsecret value and
+; your associate ID in the amazonassociate value.
+;
+; IMPORTANT: Review content providers' terms of service before turning them on.
+;            Terms may change, and not all content sources are appropriate for all
+;            applications.  The existence of functionality in VuFind does not imply
+;            suitability for any particular situation.
+[Content]
+; You can define the cover size used by each template: false (to disable covers)
+; or size (small, medium, or large). A colon separated list may be used to try
+; multiple sizes in a particular order. All legal template values and default
+; values are reflected in the examples below. Uncomment the appropriate lines to
+; make changes.
+;coversize[checkedout] = small
+;coversize[collection-info] = medium
+;coversize[core] = medium
+;coversize[holds] = small
+;coversize[illrequests] = small
+;coversize[list-entry] = small
+;coversize[RandomRecommend] = "small:medium"
+;coversize[result-grid] = large
+;coversize[result-list] = small
+;coversize[storageretrievalrequests] = small
+
+; Alternatively, if you wish to disable covers completely, you may set the
+; coversize setting to false:
+;coversize = false
+
+; You can select Syndetics, LibraryThing, Summon, Amazon, Booksite, OpenLibrary,
+; Contentcafe, Buchhandel.de, Google Books, BrowZine and/or LocalFile.
+;   Note: BrowZine requires you to have BrowZine.ini configured appropriately.
+;   Note: Summon service takes a Serials Solutions client key, NOT Summon API key!
+;   For LocalFile:PathToFile, you may use a combination of directory path information
+;        and tokens for filename and image type. If you have multiple directories
+;        in which you have stored coverimages, you can specify multiple paths to search
+;        by specifying multiple LocalFile:PathToFile in the coverage images list below.
+;        Allowed tokens:
+;          %anyimage%         - Match known image file extensions (gif, jpg, etc.)
+;          %isbn10%           - 10-digit ISBN
+;          %isbn13%           - 13-digit ISBN
+;          %issn%             - ISSN
+;          %oclc%             - OCLC Number
+;          %recordid%         - Bibliographic record ID
+;          %size%             - Size (small/medium/large)
+;          %source%           - Search backend of record (e.g. Summon, Solr, etc.)
+;          %upc%              - UPC Number
+;          %vufind-home%      - The VUFIND_HOME environment variable
+;          %vufind-local-dir% - The VUFIND_LOCAL_DIR environment variable
+;        Example: LocalFile:%vufind-local-dir%/path/to/file/%size%/issn/%issn%.%anyimage%
+;coverimages     = Syndetics:MySyndeticsId,Amazon:MyAccessKeyId,Booksite,LibraryThing:MyLibraryThingId,Google,OpenLibrary,Summon:MySerialsSolutionsClientKey,Contentcafe:MyContentCafeID,BrowZine,LocalFile:PathToFile
+
+; This setting controls which services will have images cached on your local disk.
+; Set to true to cache all applicable services. Set to false to disable caching. Set
+; to a comma-separated list of services (e.g. "Syndetics,OpenLibrary") to cache only
+; a subset of selected services. Default = true. Note that due to terms of service,
+; some services will never have images cached even if caching is enabled.
+coverimagesCache = true
+
+; This setting controls which proxied image URLs will be cached to local disk (when
+; using the ?proxy= parameter of the standard /Cover/Show routes). The setting may
+; contain one or more regular expressions matching hostnames. The example
+; below will match any images from the mylibrary.edu domain; you can also use
+; "/.*/" to turn on caching for all proxied images.
+;coverproxyCache[] = "/.*\.?mylibrary\.edu/"
+
+; These settings control the image to display when no book cover is available.
+; If makeDynamicCovers is not false and the GD library is installed, VuFind will draw
+; cover images on the fly. See [DynamicCovers] below for more settings. If set to
+; a non-Boolean value, for legacy reasons, the makeDynamicCovers setting will
+; be used as the backgroundMode setting of [DynamicCovers] if that setting is unset.
+;makeDynamicCovers = true
+
+; Otherwise, you can use noCoverAvailableImage to specify a
+; path relative to the base of your theme directory for a static image to display.
+noCoverAvailableImage = images/noCover2.gif
+
+; You can select from Syndetics, SyndeticsPlus, Amazon Editorial, Amazon, Booksite
+; and/or the Guardian
+;   Note: If the API key is omitted, e.g. "Guardian:", only the review title, byline,
+;         Guardian logo and a link to the full Guardian page will be displayed
+;   Note: The Guardian API changed in 2014; if you signed up before that date, you
+;         may need to obtain a new API key for continued access.
+reviews         = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsID,AmazonEditorial:MyAccessKeyId,Amazon:MyAccessKeyId,Booksite,Guardian:MyGuardianKeyId
+
+; You can select from Syndetics or SyndeticsPlus
+;excerpts        = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsId
+
+; This setting can be used to hide review/excerpt tabs on the record page when
+; no content is available from the providers. By default it is turned off. You
+; can turn it on for all relevant tabs by setting it to true, or you can turn
+; it on for a comma-separated list of values (e.g. "reviews" or "excerpts" or
+; "reviews,excerpts") for selective activation. Note that hiding empty tabs will
+; make your record pages slower, since it will require extra communication with
+; content providers.
+;hide_if_empty = reviews,excerpts
+
+; You can select from Syndetics or SyndeticsPlus to add summary information to
+; the description tab.
+;summaries = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsId
+
+; You can select from Syndetics or SyndeticsPlus to load Tables of Contents
+;toc = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsId
+
+; You can select from Syndetics or SyndeticsPlus
+;authorNotes = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsId
+
+; You can select from Wikipedia
+; See also the AuthorInfo recommendation module setting in searches.ini; this
+; includes notes on improving the accuracy of Wikipedia retrievals.
+; Note for Windows users: If using Wikipedia, you may need to increase your Apache
+; heap size settings.  For details, see: https://vufind.org/jira/browse/VUFIND-630
+authors         = Wikipedia
+
+; You can look up your secret key by logging into http://aws.amazon.com and clicking
+; "Access Identifiers" under "Your Account".
+;amazonsecret    = MyAmazonSecretKey
+
+; You can sign up for an associate ID by logging into
+; https://affiliate-program.amazon.com .  Please make sure your instance of VuFind
+; complies with Amazon's agreements before enabling this feature.
+;amazonassociate = MyAmazonAssociateID
+
+; You can select from Google, OpenLibrary, HathiTrust.  You should consult
+; https://developers.google.com/books/branding before using Google Book Search.
+;previews       = Google,OpenLibrary,HathiTrust
+
+; This setting controls whether or not cover images are linked to previews when
+; available. Legal settings are false (never link), * (always link; default), or
+; a comma-separated list of templates in which linking should occur (see coversize
+; above for a list of legal values).
+;linkPreviewsToCovers = *
+
+; Possible HathiRights options = pd,ic,op,orph,und,umall,ic-world,nobody,pdus,cc-by,cc-by-nd,
+; cc-by-nc-nd,cc-by-nc,cc-by-nc-sa,cc-by-sa,orphcand,cc-zero,und-world,icus
+; Default is "pd,ic-world" if unset here.
+; See www.hathitrust.org/rights_database#Attributes for full details
+;HathiRights    = pd,ic-world,cc-by,cc-by-nd,cc-by-nc-nd,cc-by-nc,cc-by-nc-sa,cc-by-sa,cc-zero,und-world
+
+; Possible GoogleBooks options full,partial,noview
+; options can be set for each / either of link or tab
+; Link makes a button appear in search results / record view
+; Tab makes a tab with an embedded preview appear on record view
+; Default is "GoogleOptions['link'] = full,partial" if nothing
+; is set here.
+; see https://developers.google.com/books/docs/dynamic-links#json-results-format
+;GoogleOptions['link']  = full,partial
+;GoogleOptions['tab']  = partial
+
+; OpenLibrary currently offers the same options/default as GoogleBooks (above):
+;OpenLibraryOptions  = full,partial
+
+; An API key is needed to interact with the Europeana API (see the EuropeanaResults
+; recommendation module in searches.ini for more information)
+;europeanaAPI = INSERTKEY
+
+; Geographic Display
+; These configuration settings have been superseded by the geofeatures.ini file.
+; See the [MapTab] section of the geofeatures.ini file for more information.
+
+; This section controls the behavior of the cover generator when makeDynamicCovers
+; above is non-false.
+;
+; Note that any of these settings may be filtered to be size-specific by subscripting
+; the key with a size. You can use a key of * for a default to use when a specific
+; size is not matched. This allows adjustment of certain elements for different
+; thumbnail sizes. See the "size" setting below for an example.
+[DynamicCovers]
+; This controls the background layer of the generated image; options:
+; - solid: display a solid color
+; - grid: display a symmetrical random pattern seeded by title/callnumber
+;backgroundMode = grid
+
+; This controls the text layer of the generated image; options:
+; - default: display a title at the top and an author at the bottom
+; - initial: display only the first letter of the title as a stylized initial
+;textMode = default
+
+; Font files specified here should exist in the css/font subdirectory of a theme.
+; Some options are available by default inside the root theme.
+;authorFont = "Roboto-Light.ttf"
+;titleFont = "RobotoCondensed-Bold.ttf"
+
+; In 'default' textMode, covers are generated using title and author name; VuFind
+; will try to display everything by doing the following: break the title into
+; lines, and if the title is too long (more than maxTitleLines lines), it will
+; display ellipses at the last line.
+;
+; All text will be drawn using the specified textAlign alignment value using the
+; relevant titleFontSize or authorFontSize setting, except that author names will
+; be reduced to the minAuthorFontSize option if needed, and if that doesn't make
+; it fit, text will be aligned left and truncated.
+;
+; When using 'initial' textMode, maxTitleLines and author-related settings are
+; ignored as they do not apply.
+;textAlign = center
+;titleFontSize = 9
+;authorFontSize = 8
+;minAuthorFontSize = 7
+;maxTitleLines = 4
+
+; All color options support the same basic set of values:
+; - The 16 named colors from HTML4
+; - Arbitrary HTML hex colors in the form #RRGGBB (e.g. #FFFF00 for yellow)
+; Some color options also support additional options.
+; - authorFillColor,titleFillColor: the main color used
+; - authorBorderColor,titleBorderColor: the color used to make a border; "none" is
+;   a legal option in addition to colors.
+; - baseColor: When using grid backgrounds, you may also choose a base color drawn
+;   beneath the grid. Default is white.
+; - accentColor: When using solid backgrounds, this is the background color; when
+;   using grid backgrounds, this is the color of the grid pattern beneath the text.
+;   You may set this to "random" to select a random color seeded with text from
+;   the cover and adjusted with the "lightness" and "saturation" settings below.
+;titleFillColor = black
+;titleBorderColor = none
+;authorFillColor = white
+;authorBorderColor = black
+;baseColor = white
+;accentColor = random
+; Note: lightness and saturation are only used when accentColor = random. Legal
+; ranges are 0-255 for each value.
+;lightness = 220
+;saturation = 80
+
+; These settings control the size of the image -- if size is a single number, a
+; square will be created; if it is a string containing an "x" (i.e. 160x190) it
+; defines a WxH rectangle. wrapWidth constrains the text size (and must be no
+; larger than the width of the canvas). topPadding and bottomPadding push the
+; text away from the edges of the canvas.
+;size[*] = 128
+;size[medium] = 200
+;size[large] = 500
+;topPadding = 19
+;bottomPadding = 3
+;wrapWidth = 110
+
+; This section is needed for Buchhandel.de cover loading. You need an authentication
+; token. It may also be necessary to customize your templates in order to comply with
+; terms of service; please look at http://info.buchhandel.de/handbuch_links for
+; details before turning this on.
+[Buchhandel]
+url = "https://api.vlb.de/api/v1/cover/"
+; token = "XXXXXX-XXXX-XXXXX-XXXXXXXXXXXX"
+
+[QRCode]
+; This setting controls the image to display when no qrcode is available.
+; The path is relative to the base of your theme directory.
+;noQRCodeAvailableImage = images/noQRCode.gif
+
+; Should we show QR codes in search results?
+;showInResults = true
+
+; Should we show QR codes on record pages?
+;showInCore = true
+
+; If you are using Syndetics Plus for *any* content, set plus = true
+; and set plus_id to your syndetics ID.  This loads the javascript file.
+; Syndetics vs. SyndeticsPlus: SyndeticsPlus has nice formatting, but loads slower
+; and requires javascript to be enabled in users' browsers.
+; set use_ssl to true if you serve your site over ssl and you
+; use SyndeticsPlus to avoid insecure content browser warnings
+; (or if you just prefer ssl)
+; NOTE: SyndeticsPlus is incompatible with the tabs/accordion [List] views in
+;       searches.ini. Do not turn it on if you are using these optional features.
+[Syndetics]
+use_ssl = false
+plus = false
+;plus_id = "MySyndeticsId"
+; timeout value (in seconds) for API calls:
+timeout = 10
+
+; Booksite CATS Enhanced Content - cover images, reviews, description, etc.
+[Booksite]
+url = "https://api.booksite.com"
+;key = "XXXXXXXXXXXXXXXXX"
+
+; Content Cafe is a subscription service from Baker & Taylor. If you are using this
+; service (see the [Content] section above for details), you MUST uncomment and set
+; the password (pw) setting. You may also change the API base URL (url) if needed.
+[Contentcafe]
+;url              = "http://contentcafe2.btol.com"
+;pw               = "xxxxxx"
+
+; Summon is optional; this section is used for your API credentials. apiId is the
+; short, human-readable identifier for your Summon account; apiKey is the longer,
+; non-human-readable secret key. See also the separate Summon.ini file.
+;[Summon]
+;apiId        = myAccessId
+;apiKey       = mySecretKey
+
+; This section must be filled in if you plan to use the optional WorldCat
+; search module. Otherwise, it may be ignored.
+;[WorldCat]
+;Your WorldCat search API key
+;apiKey          = "long-search-api-key-goes-here"
+;Your holdings symbol (usually a three-letter code) - used for excluding your
+; institution's holdings from the search results.
+;OCLCCode        = MYCODE
+
+; This section must be filled in to use Relais (E-ZBorrow) functionality. When
+; activated, this function will allow users to place ILL requests on unavailable
+; items through the record holdings tab.
+;
+; If you set apikey below, requests may be made from within VuFind through a
+; pop-up; if you omit apikey but set loginUrl and symbol, links will be provided
+; to Relais. Setting loginUrl and symbol is strongly recommended in all cases,
+; since links will be used as a fallback if the API fails.
+;[Relais]
+; Your library's holdings symbol (e.g. PVU for Villanova)
+;symbol="XYZ"
+; The pickup location to use for your institution (currently multiple pickup
+; locations are not supported here).
+;pickupLocation = "DEFAULT"
+; Barcode number (or other user ID) to use for lookups when none is provided
+;patronForLookup="99999999"
+; API key (may vary for testing vs. production)
+;apikey="your-relais-api-key-goes-here"
+; Timeout for HTTP requests (in seconds; set high, as Relais can be slow)
+;timeout = 500
+; Your institution's login URL for the remote Relais system (used to provide
+; a link when the API fails)
+;loginUrl = https://e-zborrow.relais-host.com/user/login.html
+
+; TEST VALUES (uncomment for testing)
+;group="DEMO"
+;authenticateurl="https://demo.relais-host.com/portal-service/user/authentication"
+;availableurl="https://demo.relais-host.com/dws/item/available"
+;addurl="https://demo.relais-host.com/dws/item/add"
+
+; PRODUCTION VALUES (uncomment for live use)
+;group="EZB"
+;authenticateurl="https://e-zborrow.relais-host.com/portal-service/user/authentication"
+;availableurl="https://e-zborrow.relais-host.com/dws/item/available"
+;addurl="https://e-zborrow.relais-host.com/dws/item/add"
+
+; DPLA key -- uncomment and fill in to use DPLATerms recommendations (see also
+; searches.ini).
+;[DPLA]
+;apiKey = http://dp.la/info/developers/codex/policies/#get-a-key
+
+; These settings affect dynamic DOI-based link inclusion; this can provide links
+; to full text or contextual information.
+[DOI]
+; This setting controls whether or not DOI-based links are enabled, and which
+; API is used to fetch the data. Currently supported options: BrowZine (requires
+; credentials to be configured in BrowZine.ini), Unpaywall or false (to disable). Disabled
+; by default.
+;resolver = BrowZine
+
+;unpaywall_api_url = "https://api.unpaywall.org/v2"
+; Unpaywall needs an email adress, see https://unpaywall.org/products/api
+;unpaywall_email = "your@email.org"
+
+; The following settings control where DOI-based links are displayed:
+show_in_results = true      ; include in search results
+show_in_record = false      ; include in core record metadata
+show_in_holdings = false    ; include in holdings tab of record view
+
+; These settings affect OpenURL generation and presentation; OpenURLs are used to
+; help users find resources through your link resolver and to manage citations in
+; Zotero.
+[OpenURL]
+; If a resolver base URL is enabled, it will be used to link from records to your
+; OpenURL resolver. An OpenURL resolver is typically used to e.g. link to full text
+; from article metadata, but it may provide other services too. Extra parameters may
+; be added if necessary.
+;url             = "http://openurl.myuniversity.edu/sfx_local"
+
+; This string will be included as part of your OpenURL referer ID (the full string
+; will be "info:sid/[your rfr_id setting]:generator").  You may be able to configure
+; special behavior in your link resolver based on this ID -- for example, you may
+; wish to prevent the resolver from linking to VuFind when links came from VuFind
+; (to avoid putting a user in an infinite loop).
+rfr_id          = vufind.svn.sourceforge.net
+
+; By specifying your link resolver type, you can allow VuFind to optimize its
+; OpenURLs for a particular platform.  Current legal values: "sfx", "360link",
+; "EZB", "Redi", "Alma", "demo" or "generic" (default is "generic" if commented out;
+; "demo" generates fake values for use in testing the embed setting below).
+;resolver        = sfx
+
+; If you want OpenURL links to open in a new window, set this setting to the
+; desired Javascript window.open parameters.  If you do not want a new window
+; to open, set this to false or comment it out.
+window_settings = "toolbar=no,location=no,directories=no,buttons=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=550,height=600"
+
+; If you want to display a graphical link to your link resolver, uncomment the
+; settings below.  graphic should be a URL; graphic_width and graphic_height
+; should be sizes in pixels.
+;graphic = "http://myuniversity.edu/images/findIt.gif"
+;graphic_width = 50
+;graphic_height = 20
+
+; If your link resolver can render an image in response to an OpenURL, you can
+; specify the base URL for image generation here:
+;dynamic_graphic = "http://my-link-resolver/image"
+
+; If dynamic_graphic is set above, the dynamic image can be used instead of the
+; standard text or static-image-based OpenURL link (true), it can be disabled
+; (false), or it can be displayed in addition to the regular link ("both").
+;image_based_linking_mode = both
+
+; The following settings control where OpenURL links are displayed:
+show_in_results = true      ; include in search results
+show_in_record = false      ; include in core record metadata
+show_in_holdings = false    ; include in holdings tab of record view
+
+; If set to true, this setting will attempt to embed results from the link
+; resolver directly in search results instead of opening a new window or page.
+; This will override the window_settings option if set! Embedding is currently
+; unsupported when the resolver setting above is set to "other".
+embed = false
+
+; When embed is true and this is set to true results from the link resolver will
+; be loaded automatically (default is false, which requires a user click to trigger
+; the loading). Alternatively you can provide a comma-separated list of view areas
+; (cf. show_in_* settings) to autoload embedded OpenURLs only in certain views.
+; Notice: autoloading in results view might put some load on your linkresolver (each
+; results view could perform searches.ini->[General]->default_limit requests). You
+; might reduce load on the linkresolver by using the resolver_cache setting (see
+; below).
+embed_auto_load = false
+
+; When embed is true, you can set this to an absolute path on your system in order
+; to cache link resolver results to disk.  Be sure that the chosen directory has
+; appropriate permissions set!  Leave the setting commented out to skip caching.
+; Note that the contents of this cache will not be expired by VuFind; you should
+; set up an external process like a cron job to clear out the directory from time
+; to time.
+;resolver_cache = /usr/local/vufind/resolver_cache
+
+; This setting controls whether we should display an OpenURL link INSTEAD OF other
+; URLs associated with a record (true) or IN ADDITION TO other URLs (false).
+replace_other_urls = true
+
+; EZproxy is optional.  This section only needs to exist if you
+; are using EZProxy to provide off-site access to online materials.
+;[EZproxy]
+;host            = http://proxy.myuniversity.edu
+
+; By default, when the 'host' setting above is active, VuFind will prefix links in
+; records using EZproxy's "?qurl=" mechanism. If you need to set a host for ticket
+; authentication (below) but you want to disable the prefixing behavior, set this
+; to false.
+;prefixLinks = true
+
+; Uncomment the following line and change the password to something secret to enable
+; EZproxy ticket authentication.
+;secret = "verysecretpassword"
+;
+; To enable ticket authentication in EZproxy, you will also need the following in
+; EZproxy's user.txt or ezproxy.usr for older versions (without the leading
+; semicolons and spaces):
+;
+; ::CGI=https://vufind-server/ExternalAuth/EzproxyLogin?url=^R
+; ::Ticket
+; TimeValid 10
+; SHA512 verysecretpassword
+;
+; Uncomment and modify the following line to use another hashing algorithm with the
+; EZproxy authentication if necessary. SHA512 is the default, but it requires at
+; least EZproxy version 6.1. Use "SHA1" for older EZproxy versions, and remember to
+; replace SHA512 with SHA1 also in EZproxy's configuration file.
+;secret_hash_method = "SHA512"
+
+; Uncomment the following line to disable relaying of user name to EZproxy on ticket
+; authentication:
+;anonymous_ticket = true
+; Uncomment the following line to disable logging of successful ticket
+; authentication requests in VuFind:
+;disable_ticket_auth_logging = true
+
+; These settings affect RefWorks record exports.  They rarely need to be changed.
+[RefWorks]
+vendor          = VuFind
+url             = https://www.refworks.com
+
+; These settings affect EndNote Web record exports.  They rarely need to be changed.
+[EndNoteWeb]
+vendor          = VuFind
+url             = https://www.myendnoteweb.com/EndNoteWeb.html
+
+; These settings affect your OAI server if you choose to use it.
+;
+; If identifier is set, its value will be used as part of the standard OAI
+; identifier prefix.  It should only ever be set to a domain name that you
+; control!  If it is not set, your ID values will not be prefixed.
+;
+; If admin_email is not set, the main email under [Site] will be used instead.
+;
+; page_size may be used to specify the number of records returned per request.
+; Default is 100. A higher number may improve overall harvesting performance, but
+; will also make a single response page larger and slower to produce.
+;
+; If set_field is set, the named Solr field will be used to generate sets on
+; your OAI-PMH server.  If it is not set, sets will not be supported.
+;
+; If set_query is set (as an array mapping set names to Solr queries -- see
+; examples below), the specified queries will be exposed as OAI sets.  If
+; you use both set_field and set_query, be careful about the names you choose
+; for your set queries. set_query names will trump set_field values when
+; there are collisions.
+;
+; default_query may be used to specify a filter for the default set, i.e. records
+; returned when a set is not specified.
+;
+; If vufind_api_format_fields is set, the listed fields (as defined in
+; SearchApiRecordFields.yaml) are returned when metadata prefix
+; "oai_vufind_json" is used.
+;
+; record_format_filters allows mapping from requested OAI metadataPrefix to query
+; filters. They can be used e.g. to limit results to records that can be returned in
+; the requested format.
+;
+; delete_lifetime controls how many days' worth of deleted records to include in
+; responses. Records deleted before the cut-off will not be included in responses.
+; Omit this setting to return all deleted records. This can be useful for long-lived
+; systems with many deleted records, to prevent full harvests from becoming unwieldy.
+;
+;[OAI]
+;identifier       = myuniversity.edu
+;repository_name  = "MyUniversity Catalog"
+;admin_email      = oai@myuniversity.edu
+;page_size        = 1000
+;set_field        = "format"
+;set_query['eod_books'] = "institution:kfu AND publishDate:[1911 TO 1911]"
+;set_query['eod_ebooks'] = "format:eBook"
+;default_query = "institution:kfu"
+;vufind_api_format_fields = "id,authors,cleanIsbn,cleanIssn,formats,title"
+;record_format_filters[marc21] = "record_format:marc"
+;delete_lifetime = 365
+
+; Proxy Server is Optional.
+[Proxy]
+;host = your.proxy.server
+;port = 8000
+
+; Uncomment following line to set proxy type to SOCKS 5
+;type = socks5
+
+; Default HTTP settings can be loaded here. These values will be passed to
+; the \Zend\Http\Client's setOptions method.
+[Http]
+;sslcapath = "/etc/ssl/certs" ; e.g. for Debian systems
+;sslcafile = "/etc/pki/tls/cert.pem" ; e.g. for CentOS systems
+
+;timeout = 30 ; default timeout if not overridden by more specific code/settings
+
+; Example: Using a CURL Adapter instead of the the defaultAdapter (Socket); note
+; that you may also need to install CURL and PHP/CURL packages on your server.
+;adapter = 'Zend\Http\Client\Adapter\Curl'
+
+; Spelling Suggestions
+;
+; Note: These settings affect the VuFind side of spelling suggestions; you
+; may also wish to adjust some Solr settings in solr/biblio/conf/schema.xml
+; and solr/biblio/conf/solrconfig.xml.
+[Spelling]
+enabled = true
+; Number of suggestions to display on screen. This list is filtered from
+;   the number set in solr/biblio/conf/solrconfig.xml so they can differ.
+limit   = 3
+; Show the full modified search phrase on screen
+;   rather then just the suggested word
+phrase = false
+; Offer expansions on terms as well as basic replacements
+expand  = true
+; Turning on 'simple' spell checking will improve performance,
+;  by ignoring the more complicated 'shingle' (mini phrases)
+;  based dictionary.
+simple = false
+; This setting skips spell checking for purely numeric searches; spelling
+; suggestions on searches for ISBNs and OCLC numbers are not generally very
+; useful.
+skip_numeric = true
+
+; These settings control what events are logged and where the information is
+; stored.
+;
+; VuFind currently supports four logging levels: alert (severe fatal error),
+; error (fatal error), notice (non-fatal warning) and debug (informational).
+;
+; Each logging level can be further broken down into five levels of verbosity.
+; You can specify the desired level by adding a dash and a number after the
+; level in the configuration string -- for example, alert-2 or error-5.
+; The higher the number, the more detailed the logging messages.  If verbosity
+; is not specified, it defaults to 1 (least detailed).
+;
+; Several logging methods are available, and each may be configured to log any
+; combination of levels.
+;
+; You may enable multiple logging mechanisms if you want -- in fact, it is
+; recommended, since the failure of one logging mechanism (i.e. database down,
+; file system full) may then be reported to another.
+;
+; If database is uncommented, messages will be logged to the named MySQL table.
+; The table can be created with this SQL statement:
+; CREATE TABLE log_table ( id INT NOT NULL AUTO_INCREMENT,
+;     logtime TIMESTAMP NOT NULL, ident CHAR(16) NOT NULL,
+;     priority INT NOT NULL, message TEXT, PRIMARY KEY (id) );
+;
+; If file is uncommented, messages will be logged to the named file.  Be sure
+; that Apache has permission to write to the specified file!
+;
+; If email is uncommented, messages will be sent to the provided email address.
+; Be careful with this setting: a flood of errors can easily bog down your mail
+; server!
+[Logging]
+;database       = log_table:alert,error,notice,debug
+; NOTE : Make sure the log file exists and that Apache has write permission.
+; NOTE : Windows users should avoid drive letters (eg. c:\vufind) because
+;        the colon will be used in the string parsing. "/vufind" will work
+;file           = /var/log/vufind.log:alert,error,notice,debug
+;email          = alerts@myuniversity.edu:alert-5,error-5
+
+; Get URL from https://YOURSLACK.slack.com/apps/manage/custom-integrations
+;slack = #channel_name:alert,error
+;slackurl = https://hooks.slack.com/services/your-private-details
+;slackname = "VuFind Log" ; username messages are posted under
+; You can also use the Slack settings to hook into Discord:
+; - Get your url from Server Settings > Webhooks
+; - Add /slack to the end of your url for Slack-compatible messages
+; https://discordapp.com/developers/docs/resources/webhook#execute-slackcompatible-webhook
+
+; This section can be used to specify a "parent configuration" from which
+; the current configuration file will inherit.  You can chain multiple
+; configurations together if you wish.
+[Parent_Config]
+; Full path to parent configuration file:
+;path = /usr/local/vufind/application/config/config.ini
+; Path to parent configuration file (relative to the location of this file):
+;relative_path = ../masterconfig/config.ini
+
+; A comma-separated list of config sections from the parent which should be
+; completely overwritten by the equivalent sections in this configuration;
+; any sections not listed here will be merged on a section-by-section basis.
+;override_full_sections = "Languages,AlphaBrowse_Types"
+
+; This setting is for allowing arrays to be merged with the values of their parents
+; arrays. If override_full_sections is set for a section the arrays will always be
+; overridden.
+; For legacy reasons merging of arrays is disabled by default.
+;merge_array_settings = false
+
+; This section controls which language options are available to your users.
+; If you offer more than one option, a control will appear in the user
+; interface to allow user selection.  If you only activate one language,
+; the control will be hidden.
+;
+; The name of each setting below (i.e. en, de, fr) is a language code and
+; corresponds with one of the translation files found in the web/lang
+; directory.  The value of each setting is the on-screen name of the language,
+; and will itself be subject to translation through the language files!
+;
+; The order of the settings is significant -- they will be displayed on screen
+; in the same order they are defined here.
+;
+; Be sure that this section includes the default language set in the [Site]
+; section above.
+[Languages]
+en          = "English"              ; American spellings
+;en-gb       = "English"              ; British spellings
+de          = "German"
+es          = "Spanish"
+fr          = "French"
+it          = "Italian"
+ja          = "Japanese"
+nl          = "Dutch"
+;nl-be       = "Flemish Dutch"
+pt          = "Portuguese"
+pt-br       = "Brazilian Portugese"
+zh-cn       = "Simplified Chinese"
+zh          = "Chinese"
+tr          = "Turkish"
+he          = "Hebrew"
+ga          = "Irish"
+cy          = "Welsh"
+el          = "Greek"
+ca          = "Catalan"
+eu          = "Basque"
+ru          = "Russian"
+cs          = "Czech"
+fi          = "Finnish"
+sv          = "Swedish"
+pl          = "Polish"
+da          = "Danish"
+sl          = "Slovene"
+ar          = "Arabic"
+bn          = "Bengali"
+gl          = "Galician"
+vi          = "Vietnamese"
+hr          = "Croatian"
+hi          = "Hindi"
+
+; This section contains special cases for languages such as right-to-left support
+[LanguageSettings]
+; Comma-separated list of languages to display in right-to-left mode
+rtl_langs = "ar,he"
+
+; This section controls the behavior of the Browse module.  The result_limit
+; setting controls the maximum number of results that may display in any given
+; result box on the Browse screen.  You can set to -1 for no limit; however,
+; setting a very high (or no) limit may result in "out of memory" errors if you
+; have a large index!
+[Browse]
+result_limit    = 100
+tag             = true      ; allow browsing of Tags
+dewey           = false     ; allow browsing of Dewey Decimal call numbers
+lcc             = true      ; allow browsing of LC call numbers
+author          = true      ; allow browsing of authors
+topic           = true      ; allow browsing of subject headings
+genre           = true      ; allow browsing of genre subdivisions
+region          = true      ; allow browsing of region subdivisions
+era             = true      ; allow browsing of era subdivisions
+; You can use this setting to change the default alphabet provided for browsing:
+;alphabet_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+; Uncomment to sort lists alphabetically (instead of by popularity); note that
+; this will not changed the values returned -- you will still get only the
+; <result_limit> most popular entries -- it only affects display order.
+;alphabetical_order = true
+
+; This section controls the availability of export methods.
+;
+; Each entry may be a comma-separated list of contexts in which the export
+; option will be presented. Valid options:
+;
+; bulk - Included in batch export contexts
+; record - Included in single-record export contexts
+;
+; If you simply set a field to true, only "record" mode will be enabled.
+; If you set a field to false, all export contexts will be disabled.
+;
+; Note that some options may be disabled for records that do not support them,
+; regardless of the setting chosen here.  You can edit the separate export.ini
+; file to add new export formats and change the behavior of existing ones.
+[Export]
+RefWorks = "record,bulk"
+EndNote = "record,bulk"
+EndNoteWeb = "record,bulk"
+MARC = false
+MARCXML = false
+RDF = false
+BibTeX = false
+RIS = false
+
+[BulkExport]
+; Export behavior to use when no bulkExportType setting is found in the matching
+; format section of export.ini; default is 'link' if not overridden below. See
+; export.ini for more details on available options.
+;defaultType = download
+
+;AddThis is optional. It uses the Add This tool available from www.addthis.com
+; and requires the username generated when an analytics account is registered.
+;[AddThis]
+;key = yourUsername
+
+; This section controls how item status information is presented in search results.
+[Item_Status]
+; Usually, there is only one location or call number for each item; however, when
+; multiple values are found, there are several possible behaviors:
+;     first = display the first value found, ignore the rest
+;     all   = show all of the values found, separated by commas
+;     msg   = show a message like "Multiple Call Numbers" or "Multiple Locations"
+;     group = show availability statuses for each location on a separate line,
+;             followed by callnumber information (valid for multiple_locations only)
+multiple_call_nos = first
+multiple_locations = msg
+
+; If your ILS driver supports services, VuFind will display a more detailed
+; availability message. This setting may be used to indicate that one particular
+; status is preferred over all others and should be displayed by itself when
+; found. This is useful because some drivers will always provide both "loan" and
+; "presentation" services, but most users will only care about "loan" (since in-
+; library use is implied by the ability to borrow an item). Set this to false to
+; always display all services.
+preferred_service = "loan"
+
+; Show the full location, call number, availability for each item.
+; You can customize the way each item's status is displayed by overriding the
+; ajax/status-full.phtml template.
+; When enabled, this causes the multiple_call_nos, multiple_locations and
+; preferred_service settings to be ignored.
+show_full_status = false
+
+; You can set this to the name of an alphabetic browse handler (see the
+; [AlphaBrowse_Types] section) in order to link call numbers displayed on the
+; holdings tab and in status messages to a specific browse list. Set to false
+; to disable call number linking.
+callnumber_handler = false
+
+; This section controls the behavior of the Record module.
+[Record]
+; Set this to true in order to enable "next" and "previous" links to navigate
+; through the current result set from within the record view.
+next_prev_navigation = false
+
+; Set this to true in order to enable "first" and "last" links to navigate
+; through the content result set from within the record view. Note, this
+; may cause slow behavior with some installations. The option will only work
+; when next_prev_navigation is also set to true.
+first_last_navigation = false
+
+; Setting this to true will cause VuFind to skip the results page and
+; proceed directly to the record page when a search has only one hit.
+jump_to_single_search_result = false
+
+; You can enable this setting to show links to related MARC records using certain
+; 7XX fields. Just enter a comma-separated list of the MARC fields that you wish
+; to make use of.
+;marc_links = "760,762,765,767,770,772,773,774,775,776,777,780,785,787"
+; In the marc_links_link_types enter the fields you want the module to use to
+; construct the links. The module will run through the link types in order
+; until it finds one that matches. If you don't have id numbers in the fields,
+; you can also use title to construct a title based search. id represents a raw
+; bib id, dlc represents an LCCN.  Default setting:
+;marc_links_link_types = id,oclc,dlc,isbn,issn,title
+; Set use_visibility_indicator to false if you want to show links that are marked as
+; "Do not show" in the MARC record (indicator 1). Otherwise, these links will be
+; suppressed. (Default = true)
+;marc_links_use_visibility_indicator = false
+
+; When displaying publication information from 260/264, this separator will be
+; placed between repeating subfield values (default is to rely on existing ISBD
+; punctuation, but this can be used when ISBD punctuation is absent (e.g. ", ").
+;marcPublicationInfoSeparator = " "
+
+; When displaying publication information from 260/264, this can be set to true
+; to make 264 information completely replace 260 information. Default is false,
+; which will display information from 260 AND 264 when both fields are populated.
+; Note that this only affects display, not indexing; both fields will always be
+; made searchable.
+;replaceMarc260 = false
+
+; Set the URI-pattern of the server which serves the raw Marc-data. (see
+; https://vufind.org/wiki/configuration:remote_marc_records for more information
+; on how to set up a remote service for raw Marc-data)
+;remote_marc_url = http://127.0.0.1/%s
+
+; You can use this setting to hide holdings information for particular named locations
+; as returned by the catalog.
+hide_holdings[] = "World Wide Web"
+
+; This array controls which Related modules are used to display sidebars on the
+; record view page.
+;
+; Available options:
+;    Channels - Display links to channels of content related to record
+;    Similar - Similarity based on Solr lookup
+;    WorldCatSimilar - Similarity based on WorldCat lookup
+related[] = "Similar"
+
+; This setting controls which citations are available; set to true for all supported
+; options (default); set to false to disable citations; set to a comma-separated list
+; to activate only selected formats (available options: APA, Chicago, MLA). The
+; comma-separated list option may also be used to customize citation display order.
+;citation_formats = APA,Chicago,MLA
+
+; The following two sections control the Alphabetic Browse module.
+[AlphaBrowse]
+; This setting controls how many headings are displayed on each page of results:
+page_size = 20
+; How many headings to show before the match (or the spot where the match
+; would have been found). Default is 0 for backwards compatibility.
+rows_before = 0
+; highlight the match row (or spot where match would have been)? default false
+highlighting = false
+; SEE ALSO: the General/includeAlphaBrowse setting in searchbox.ini, for including
+; alphabrowse options in the main search drop-down options.
+
+; This section controls the order and content of the browse type menu in the
+; Alphabetic Browse module.  The key is the browse index to use, the value is the
+; string to display to the user (subject to translation).
+[AlphaBrowse_Types]
+topic = "By Topic"
+author = "By Author"
+title = "By Title"
+lcc = "By Call Number"
+;dewey = "By Call Number"
+
+; This section controls the return of extra columns for the different browses.
+; The key is the browse index, the value is a colon-separated string of extra
+; Solr fields to return for display to the user.
+; Values should be in translation file as browse_value.
+[AlphaBrowse_Extras]
+title = "author:format:publishDate"
+lcc = title
+dewey = title
+
+; This section allows you to configure the values used for Cryptography; the
+; HMACkey can be set to any value you like and should never be shared.  It is used
+; to prevent users from tampering with certain URLs (for example, "place hold" form
+; submissions)
+[Security]
+HMACkey = mySuperSecretValue
+
+; This section sets global defaults for caches; file caching is used by default.
+; A custom directory for caching can be defined by the environment variable
+; VUFIND_CACHE_DIR (see httpd-vufind.conf). The default location is inside the
+; local settings directory.
+[Cache]
+; Set time to live value for Zend caches (in seconds), 0 means maximum possible.
+;ttl = 0
+; Override umask for cache directories and files.
+;umask = 022
+; Permissions for Zend-created cache directories and files, subject to umask
+; Default dir_permission seems to be 0700.
+;dir_permission = 0700
+; Default file_permission seems to be 0600.
+;file_permission = 0600
+
+; This section controls the "Collections" module -- the special view for records
+; that represent collections, and the mechanism for browsing these records.
+[Collections]
+; Control whether or not the collections module is enabled in search results.
+; If set to true any search results which are collection level items will
+; link to the respective collections page rather than the record page
+; (default = false).
+;collections = true
+; Control default tab of Collection view (default = CollectionList); see also
+; CollectionTabs.ini.
+;defaultTab = CollectionList
+; This controls where data is retrieved from to build the Collections/Home page.
+; It can be set to Index (use the Solr index) or Alphabetic (use the AlphaBrowse
+; index). Index is subject to "out of memory" errors if you have many (150000+)
+; collections; Alphabetic has no memory restrictions but requires generation of
+; a browse index using the index-alphabetic-browse tool.  (default = Index)
+;browseType = Index
+; This string is the delimiter used between title and ID in the hierarchy_browse
+; field of the Solr index.  Default is "{{{_ID_}}}" but any string may be used;
+; be sure the value is consistent between this configuration and your indexing
+; routines.
+;browseDelimiter = "{{{_ID_}}}"
+; This controls the page size within the Collections/Home page (default = 20).
+;browseLimit = 20
+; List of record routes that are converted to collection routes (used to map
+; route names when a record identifies itself as a collection and the collections
+; setting above is true).
+route[record] = collection
+route[search2record] = search2collection
+
+; This section addresses hierarchical records in the Solr index
+[Hierarchy]
+; Name of hierarchy driver to use if no value is specified in the hierarchytype
+; field of the Solr index.
+driver = Default
+; Should we display hierarchy trees? (default = false)
+;showTree = true
+; "Search within trees" can be disabled here if set to "false" (default = true)
+search = true
+; You can limit the number of search results highlighted when searching the tree;
+; a limit is recommended if you have large trees, as otherwise large numbers of
+; results can cause performance problems.  If treeSearchLimit is -1 or not set,
+; results will be unlimited.
+treeSearchLimit = 100
+; Whether hierarchy fields are used for linking between container records and their
+; children (default = false). This is an alternative to the full collections support
+; (see the [Collections] section), so only one of them should be enabled
+; at a time e.g. unless custom record drivers are used. When using this setting,
+; you may also wish to enable the ComponentParts tab in RecordTabs.ini.
+;simpleContainerLinks = true
+
+; This section will be used to configure the feedback module.
+; Set "tab_enabled" to true in order to enable the feedback module.
+; Forms are configured in FeedbackForms.yaml
+[Feedback]
+;tab_enabled       = true
+
+; Default values for form recipient and email subject, if not overridden for a
+; specific form in FeedbackForms.yaml
+;recipient_email   = "feedback@myuniversity.edu"
+;recipient_name    = "Your Library"
+;email_subject     = "VuFind Feedback"
+
+; This is the information for where feedback emails are sent from.
+;sender_email      = "noreply@vufind.org"
+;sender_name       = "VuFind Feedback"
+
+; Note: for additional details about stats (including additional notes on Google
+; Analytics and Piwik), look at the wiki page:
+;     https://vufind.org/wiki/configuration:usage_stats
+
+; Uncomment this section and provide your API key to enable Google Analytics. Be
+; sure to set the "universal" setting to true once your account is upgraded to
+; Universal Analytics; see:
+; https://developers.google.com/analytics/devguides/collection/upgrade/guide
+;[GoogleAnalytics]
+;apiKey = "mykey"
+;universal = false
+
+; Uncomment this section and provide your Piwik server address and site id to
+; enable Piwik analytics. Note: VuFind's Piwik integration uses several custom
+; variables; to take advantage of them, you must reconfigure Piwik by switching
+; to its root directory and running this command to raise a default limit:
+; ./console customvariables:set-max-custom-variables 10
+[Piwik]
+;url = "http://server.address/piwik/"
+;site_id = 1
+; Uncomment the following setting to track additional information about searches
+; and displayed records with Piwik's custom variables
+;custom_variables = true
+; By default, Piwik searches are tracked using the format "Backend|Search Terms."
+; If you need to differentiate searches coming from multiple VuFind instances using
+; a shared site_id, you can set the searchPrefix to add an additional prefix to
+; the string, for example "SiteA|Backend|Search Terms." Most users will want to
+; leave this disabled.
+;searchPrefix = "SiteA|"
+; Uncomment the following setting to disable cookies for privacy reasons.
+; see https://matomo.org/faq/general/faq_157/ for more information.
+;disableCookies = true
+
+; Uncomment portions of this section to activate tabs in the search box for switching
+; between search modules. Keys are search backend names, values are labels for use in
+; the user interface (subject to translation). If you need multiple tabs for a single
+; backend, append a colon and a suffix to each backend name (e.g. Solr:main) and add
+; the filters in the [SearchTabsFilters] section.
+[SearchTabs]
+;Solr = Catalog
+;Summon = Summon
+;WorldCat = WorldCat
+;Solr:filtered = "Catalog (Main Building Books)"
+;EDS = "EBSCO Discovery Service"
+;EIT = "EBSCO Integration Toolkit"
+;Primo = "Primo Central"
+
+; Add any hidden filters in this section for search tab specific filtering
+[SearchTabsFilters]
+;Solr:filtered[] = 'building:"main library"'
+;Solr:filtered[] = "format:book"
+
+; You can bind a permission to a search tab in this section.
+; This controls to whom the tab should be displayed.
+; Use the format tabName = permission. The permission should be configured
+; in permissions.ini (who should see the tab)
+; and permissionBehavior.ini (what should be displayed instead of the tab).
+; Note that this ONLY controls whether or not the tab is displayed; if you wish to
+; restrict actual searching, you will also need to make sure that the relevant
+; controller(s) are blocking access using the same named permission.
+[SearchTabsPermissions]
+;EIT = access.EITModule
+;Primo = access.PrimoModule
+
+; Uncomment portions of this section to label searches from particular sources in the
+; search history display.  Keys are search backend names, values are labels for use in
+; the user interface (subject to translation).
+[SearchHistoryLabels]
+;Solr = Catalog
+;Summon = Summon
+;WorldCat = WorldCat
+;SolrWeb = "Library Website"
+;EDS = "EBSCO Discovery Service"
+
+; Activate Captcha validation on select forms
+; VuFind will use reCaptcha validation to prevent bots from using certain actions of
+; your instance. See http://www.google.com/recaptcha for more information on Captcha
+; and create keys for your domain.
+; You will need to provide a sslcapath in the [Http] section for your Captcha to work.
+;[Captcha]
+;siteKey  = "get your reCaptcha key at"
+;secretKey = "https://www.google.com/recaptcha/admin/create"
+; Valid theme values: dark, light
+;theme      = light
+; Valid forms values: changePassword, email, feedback, newAccount, passwordRecovery,
+;                     sms, userComments
+; Use * for all supported forms
+; Note: when "feedback" is active, Captcha can be conditionally disabled on a
+;       form-by-form basis with the useCaptcha setting in FeedbackForms.yaml.
+;forms = changeEmail, changePassword, email, newAccount, passwordRecovery, sms
+
+
+; This section can be used to display default text inside the search boxes, useful
+; for instructions. Format:
+;
+; backend = Placeholder text
+;
+; You can use a "default" setting if you want a standard string displayed across
+; all backends not otherwise specified. You can qualify backend names with a
+; colon-delimited suffix if you wish to use special placeholders in combination
+; with filtered search tabs (see [SearchTabsFilters] above).
+[SearchPlaceholder]
+;default = "Enter search terms here..."
+;Solr = "Search the catalog"
+;Solr:filtered = "Search the filtered catalog"
+;Summon = "Search Summon"
+
+; This section controls VuFind's social features.
+[Social]
+; Comments may be "enabled" or "disabled" (default = "enabled")
+comments = enabled
+; Favorite lists may be "enabled", "disabled", "public_only" or "private_only"
+; (default = "enabled")
+; The public_only/private_only settings restrict the type of list users may
+; create. If you change this to a more restrictive option, it is your responsibility
+; to update the user_list database table to update the status of existing lists.
+lists = enabled
+; The following two settings are equivalent to default_limit / limit_options in
+; searches.ini, but used to control the page sizes of lists of favorites:
+lists_default_limit   = 20
+;lists_limit_options   = 10,20,40,60,80,100
+; This section controls what happens when a record title in a favorites list
+; is clicked. VuFind can either embed the full result directly in the list using
+; AJAX or can display it at its own separate URL as a full HTML page.
+; See the [List] section of searches.ini for all available options.
+lists_view=full
+; Tags may be "enabled" or "disabled" (default = "enabled")
+; When disabling tags, don't forget to also turn off tag search in searches.ini.
+tags = enabled
+; This controls the maximum length of a single tag; it should correspond with the
+; field size in the tags database table.
+max_tag_length = 64
+; This controls whether tags are case-sensitive (true) or always forced to be
+; represented as lowercase strings (false -- the default).
+case_sensitive_tags = false
+; If this setting is set to false, users will not be presented with a search
+; drop-down or advanced search link when searching/viewing tags. This is recommended
+; when using a multi-backend system (e.g. Solr + Summon + WorldCat). If set to
+; true, the standard Solr search options and advanced search link will be shown
+; in the tag screens; this is recommended when using a Solr-only configuration.
+show_solr_options_in_tag_search = false
diff --git a/module/VuFind/tests/fixtures/content/amazon-cover b/module/VuFind/tests/fixtures/content/amazon-cover
deleted file mode 100644
index 110afc8358a8075b4ccdb55aa93338f54f3982d7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1530
zcmeHH(Qeu>6z#Y8anb-M1d4e=>n4!WQW4O!2?=@01>D9-W;=A<)PLV`0u|f3r@r<r
zx%b@b<9mG1Tm+$DU#Z9vG6$8?dZOjevRKa?X(sqU{Ia4i*d&?Vu(1`qCs=P7jzS*t
zV9-QRe??BJ{8sL0wTRjH2EdVEiOk6^WO3g{cp%uabTVJiLD7RfMo~UFkU{N2I#ukB
zVVsj_nddW&3>(iy02VLtZ1N)XJke@pat{V?7E7%PY1b>G)>G#y+@|MId??t(yNiR&
zRW>cHTRv6<GD`3fc(=*gk~tFL4Z4!nK9nYFgSZ?z*mO@C+?oOH{R#NwE#5bn72C4K
zw@vpr%tHb|DE-k<p1OT6n}K)IQu|~Jtx5x^pX2dgy1mbam|?fA>(06nzl=u1PhX;5
z+}R}YFxqtPDh$wy%ZA|hn#|)L*Vtmtnu@0PlNFfKl+<pIe<g+y3M0WjtIQv!#2^|2
z<1chgnX2`h6khe}Bn4jEf2H7q-mA1g{a<46@Ul?@dl5^sqc<_m#R%|jUl!vP3(@~)
zBl?_s5wKlJ{q2rYcQi5V(R{llbMiE>`A}O|YBJAeCk5Qc?-P=V(khqc)|6S@G<i;9
z*(Pa9)|N(jS2`td!qUj}{w%~{h_SLx%R)*2ah7XcW0QGLfg9q{T+OdP=CCX5enaHx
EH<wbz%K!iX

diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php
index 9308ea2af46..105dd246f85 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php
@@ -502,4 +502,42 @@ class UpgradeTest extends \VuFindTest\Unit\TestCase
             $results['Primo.ini']['General']['url']
         );
     }
+
+    /**
+     * Test deprecated Amazon cover content warning.
+     *
+     * @return void
+     */
+    public function testAmazonCoverWarning()
+    {
+        $upgrader = $this->getUpgrader('amazoncover');
+        $upgrader->run();
+        $warnings = $upgrader->getWarnings();
+        $this->assertTrue(
+            in_array(
+                'WARNING: You have Amazon content enabled, but VuFind no longer sup'
+                . 'ports it. You should remove Amazon references from config.ini.',
+                $warnings
+            )
+        );
+    }
+
+    /**
+     * Test deprecated Amazon review content warning.
+     *
+     * @return void
+     */
+    public function testAmazonReviewWarning()
+    {
+        $upgrader = $this->getUpgrader('amazonreview');
+        $upgrader->run();
+        $warnings = $upgrader->getWarnings();
+        $this->assertTrue(
+            in_array(
+                'WARNING: You have Amazon content enabled, but VuFind no longer sup'
+                . 'ports it. You should remove Amazon references from config.ini.',
+                $warnings
+            )
+        );
+    }
 }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Covers/AmazonTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Covers/AmazonTest.php
deleted file mode 100644
index de7b0abea5d..00000000000
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Content/Covers/AmazonTest.php
+++ /dev/null
@@ -1,175 +0,0 @@
-<?php
-
-/**
- * Unit tests for Amazon cover loader.
- *
- * PHP version 7
- *
- * Copyright (C) Villanova University 2010.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * @category VuFind
- * @package  Search
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org
- */
-namespace VuFindTest\Content\Covers;
-
-use VuFindCode\ISBN;
-
-/**
- * Unit tests for Amazon cover loader.
- *
- * @category VuFind
- * @package  Search
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org
- */
-class AmazonTest extends \PHPUnit\Framework\TestCase
-{
-    /**
-     * Amazon parameters
-     *
-     * @var array
-     */
-    protected $params = ['ResponseGroup' => 'Images', 'AssociateTag' => 'fake'];
-
-    /**
-     * Test cover loading
-     *
-     * @return void
-     */
-    public function testValidCoverLoading()
-    {
-        $expected = [
-            'small' =>
-                'http://ecx.images-amazon.com/images/I/518597FY50L._SL75_.jpg',
-            'medium' =>
-                'http://ecx.images-amazon.com/images/I/518597FY50L._SL160_.jpg',
-            'large' => 'http://ecx.images-amazon.com/images/I/518597FY50L.jpg',
-        ];
-        foreach ($expected as $size => $expectedUrl) {
-            $this->assertEquals($expectedUrl, $this->getUrl($size));
-        }
-    }
-
-    /**
-     * Test illegal size
-     *
-     * @return void
-     */
-    public function testIllegalCoverLoading()
-    {
-        $this->assertEquals(false, $this->getUrl('illegal'));
-    }
-
-    /**
-     * Test missing ISBN
-     *
-     * @return void
-     */
-    public function testMissingIsbn()
-    {
-        $this->assertEquals(false, $this->getUrl('small', ''));
-    }
-
-    /**
-     * Test broken Amazon service (we should just swallow exceptions)
-     *
-     * @return void
-     */
-    public function testServiceException()
-    {
-        $this->assertEquals(false, $this->getUrl('small', '0739313126', true));
-    }
-
-    /**
-     * Simulate retrieval of a cover URL for a particular size.
-     *
-     * @param string $size  Size to retrieve
-     * @param string $isbn  ISBN to retrieve (empty for none)
-     * @param bool   $throw Should the fake service throw an exception?
-     *
-     * @return string
-     */
-    protected function getUrl($size, $isbn = '0739313126', $throw = false)
-    {
-        $amazon = $this->getMockBuilder(__NAMESPACE__ . '\CoverAmazonMock')
-            ->setMethods(['getAmazonService'])
-            ->setConstructorArgs(['fake', 'fakesecret'])
-            ->getMock();
-        $params = [];
-        if (!empty($isbn)) {
-            $behavior = $throw
-                ? $this->throwException(new \Exception('kaboom'))
-                : $this->returnValue($this->loadFixture());
-            $amazon->expects($this->once())
-                ->method('getAmazonService')->with($this->equalTo('fakekey'))
-                ->will($this->returnValue($this->getFakeService($isbn, $behavior)));
-            $params['isbn'] = new ISBN($isbn);
-        }
-        return $amazon->getUrl('fakekey', $size, $params);
-    }
-
-    /**
-     * Create fake Amazon service
-     *
-     * @param string $isbn             ISBN to retrieve (empty for none)
-     * @param mixed  $expectedBehavior Behavior of the itemLookup method
-     *
-     * @return \ZendService\Amazon\Amazon
-     */
-    protected function getFakeService($isbn, $expectedBehavior)
-    {
-        $service = $this->getMockBuilder(__NAMESPACE__ . '\ZendAmazonMock')
-            ->setMethods(['itemLookup'])
-            ->setConstructorArgs(['fakekey', 'US', 'fakesecret'])
-            ->getMock();
-        if (!empty($isbn)) {
-            $service->expects($this->once())
-                ->method('itemLookup')
-                ->with($this->equalTo($isbn), $this->equalTo($this->params))
-                ->will($expectedBehavior);
-        }
-        return $service;
-    }
-
-    /**
-     * Load fixture
-     *
-     * @return \ZendService\Amazon\Item
-     */
-    protected function loadFixture()
-    {
-        $file = realpath(__DIR__ . '/../../../../../fixtures/content/amazon-cover');
-        return unserialize(file_get_contents($file));
-    }
-}
-
-class CoverAmazonMock extends \VuFind\Content\Covers\Amazon
-{
-    public function getAmazonService($key)
-    {
-    }
-}
-
-class ZendAmazonMock extends \ZendService\Amazon\Amazon
-{
-    public function itemLookup($asin, array $options = [])
-    {
-    }
-}
-- 
GitLab