Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable default cover images #4061

Open
wants to merge 20 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/vufind/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1318,7 +1318,7 @@ url = "https://api.vlb.de/api/v1/cover/"
[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
noQRCodeAvailableImage = images/noQRCode.gif
demiankatz marked this conversation as resolved.
Show resolved Hide resolved

; Should we show QR codes in search results?
;showInResults = true
Expand Down
43 changes: 43 additions & 0 deletions module/VuFind/src/VuFind/Exception/CoverUnavailable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

/**
* Cover Unavailable Exception
demiankatz marked this conversation as resolved.
Show resolved Hide resolved
*
* PHP version 8
*
* Copyright (C) Hebis Verbundzentrale 2024.
*
* 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 Exceptions
* @author Thomas Wagener <[email protected]>
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org/wiki/development Wiki
*/

namespace VuFind\Exception;

/**
* Cover Unavailable Exception
*
* @category VuFind
* @package Exceptions
* @author Thomas Wagener <[email protected]>
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org/wiki/development Wiki
*/
class CoverUnavailable extends NotFound implements HttpStatusInterface
{
}
52 changes: 52 additions & 0 deletions module/VuFind/src/VuFind/Exception/NotFound.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

/**
* "Not Found" Exception
*
* PHP version 8
*
* Copyright (C) Hebis Verbundzentrale 2024.
*
* 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 Exceptions
* @author Thomas Wagener <[email protected]>
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org/wiki/development Wiki
*/

namespace VuFind\Exception;

/**
* "Not Found" Exception
*
* @category VuFind
* @package Exceptions
* @author Thomas Wagener <[email protected]>
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org/wiki/development Wiki
*/
class NotFound extends \Exception implements HttpStatusInterface
{
/**
* Get HTTP status associated with this exception.
*
* @return int
*/
public function getHttpStatus()
{
return 404;
}
}
14 changes: 1 addition & 13 deletions module/VuFind/src/VuFind/Exception/RecordMissing.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,8 @@
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org/wiki/development Wiki
*/
class RecordMissing extends \Exception implements
HttpStatusInterface,
SeverityLevelInterface
class RecordMissing extends NotFound implements SeverityLevelInterface
{
/**
* Get HTTP status associated with this exception.
*
* @return int
*/
public function getHttpStatus()
{
return 404;
}

/**
* Get the logging severity level for this exception.
*
Expand Down
41 changes: 9 additions & 32 deletions module/VuFind/src/VuFind/ImageLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

namespace VuFind;

use VuFind\Exception\CoverUnavailable;

use function array_key_exists;

/**
Expand Down Expand Up @@ -74,13 +76,6 @@ class ImageLoader implements \Laminas\Log\LoggerAwareInterface
*/
protected $configuredFailImage = null;

/**
* Default image to load from theme if user-configured option fails.
*
* @var string
*/
protected $defaultFailImage = 'images/noCover2.gif';

/**
* Array containing map of allowed file extensions to mimetypes
* (to be extended)
Expand Down Expand Up @@ -159,31 +154,29 @@ protected function searchTheme($path, $formats = [''])
}

/**
* Load the user-specified "cover unavailable" graphic (or default if none
* specified).
* Load the user-specified "cover unavailable" graphic (or return status
* code 404 if none specified).
*
* @return void
* @author Thomas Schwaerzler <[email protected]>
*/
public function loadUnavailable()
{
// No setting -- use default, and don't log anything:
// No setting -- return status code 404, and don't log anything:
if (empty($this->configuredFailImage)) {
$this->loadDefaultFailImage();
return;
throw new CoverUnavailable();
}

// Setting found -- get "no cover" image from config.ini:
$noCoverImage = $this->searchTheme($this->configuredFailImage);

// If file is blank/inaccessible, log error and display default:
// If file is blank/inaccessible, log error and return status code 404:
if (
empty($noCoverImage) || !file_exists($noCoverImage)
|| !is_readable($noCoverImage)
) {
$this->debug("Cannot access '{$this->configuredFailImage}'");
$this->loadDefaultFailImage();
return;
throw new CoverUnavailable();
}

try {
Expand All @@ -192,29 +185,13 @@ public function loadUnavailable()
} catch (\Exception $e) {
// Log error and bail out if file lacks a known image extension:
$this->debug($e->getMessage());
$this->loadDefaultFailImage();
return;
throw new CoverUnavailable();
}

// Load the image data:
$this->image = file_get_contents($noCoverImage);
}

/**
* Display the default "cover unavailable" graphic.
*
* @return void
*/
protected function loadDefaultFailImage()
{
$file = $this->searchTheme($this->defaultFailImage);
if (!file_exists($file)) {
throw new \Exception('Could not load default fail image.');
}
$this->contentType = $this->getContentTypeFromExtension($file);
$this->image = file_get_contents($file);
}

/**
* Get the content-type for a file based on extension. Throw an exception if
* an illegal extension is provided.
Expand Down
1 change: 0 additions & 1 deletion module/VuFind/src/VuFind/QRCode/Loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ public function __construct($config, \VuFindTheme\ThemeInfo $theme)
$this->setThemeInfo($theme);
$this->configuredFailImage
= $config->QRCode->noQRCodeAvailableImage ?? null;
$this->defaultFailImage = 'images/noQRCode.gif';
}

/**
Expand Down
31 changes: 13 additions & 18 deletions module/VuFind/tests/unit-tests/src/VuFindTest/Cover/LoaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

use Laminas\Config\Config;
use VuFind\Cover\Loader;
use VuFind\Exception\CoverUnavailable;
use VuFindTheme\ThemeInfo;

use function strlen;
Expand Down Expand Up @@ -60,41 +61,35 @@ class LoaderTest extends \PHPUnit\Framework\TestCase
*/
public function testUtterFailure()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Could not load default fail image.');

$theme = $this->getMockBuilder(\VuFindTheme\ThemeInfo::class)
->setConstructorArgs(['foo', 'bar'])->getMock();
$theme->expects($this->once())
->method('findContainingTheme')
->with($this->equalTo(['images/noCover2.gif']))
->will($this->returnValue(false));
$loader = $this->getLoader([], null, $theme);
$this->expectException(CoverUnavailable::class);
$loader = $this->getLoader();
$loader->getImage();
}

/**
* Test that requesting a content type causes default data to load.
* Test that requesting a content type causes default data to load if configured.
*
* @return void
*/
public function testDefaultLoadingForContentType()
{
$loader = $this->getLoader();
$cfg = ['Content' => ['noCoverAvailableImage' => 'images/noCover2.gif']];
$loader = $this->getLoader($cfg);
$this->assertEquals('image/gif', $loader->getContentType());
$this->assertEquals('368', strlen($loader->getImage()));
}

/**
* Test that requesting an image causes default data to load.
* Test that requesting an image causes default data to load if configured.
* (same as above test, but with assertions in different order to
* force appropriate loading).
*
* @return void
*/
public function testDefaultLoadingForImage()
{
$loader = $this->getLoader();
$cfg = ['Content' => ['noCoverAvailableImage' => 'images/noCover2.gif']];
$loader = $this->getLoader($cfg);
$this->assertEquals('368', strlen($loader->getImage()));
$this->assertEquals('image/gif', $loader->getContentType());
}
Expand All @@ -110,10 +105,10 @@ public function testMissingUserSpecifiedFailImage()
$cfg = ['Content' => ['noCoverAvailableImage' => $badfile]];
$loader = $this->getLoader($cfg, null, null, null, ['debug']);

// We expect the loader to complain about the bad filename and load the default image:
// We expect the loader to complain about the bad filename and throw an exception:
$this->expectException(CoverUnavailable::class);
$loader->expects($this->once())->method('debug')->with($this->equalTo("Cannot access '$badfile'"));
$loader->loadUnavailable();
$this->assertEquals('368', strlen($loader->getImage()));
}

/**
Expand All @@ -127,12 +122,12 @@ public function testFailImageIllegalExtension()
$cfg = ['Content' => ['noCoverAvailableImage' => $badfile]];
$loader = $this->getLoader($cfg, null, null, null, ['debug']);

// We expect the loader to complain about the bad filename and load the default image:
// We expect the loader to complain about the bad filename and throw an exception:
$this->expectException(CoverUnavailable::class);
$expected = "Illegal file-extension 'phtml' for image '" . $this->getThemeDir() . '/'
. $this->testTheme . '/' . $badfile . "'";
$loader->expects($this->once())->method('debug')->with($this->equalTo($expected));
$loader->loadUnavailable();
$this->assertEquals('368', strlen($loader->getImage()));
}

/**
Expand Down
47 changes: 33 additions & 14 deletions module/VuFind/tests/unit-tests/src/VuFindTest/QRCode/LoaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
namespace VuFindTest\QRCode;

use Laminas\Config\Config;
use VuFind\Exception\CoverUnavailable;
use VuFind\QRCode\Loader;
use VuFindTheme\ThemeInfo;

Expand Down Expand Up @@ -60,40 +61,58 @@ class LoaderTest extends \PHPUnit\Framework\TestCase
*/
public function testUtterFailure()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Could not load default fail image.');

$theme = $this->getMockBuilder(\VuFindTheme\ThemeInfo::class)
->setConstructorArgs(['foo', 'bar'])->getMock();
$theme->expects($this->once())
->method('findContainingTheme')
->with($this->equalTo(['images/noQRCode.gif']))
->will($this->returnValue(false));
$loader = $this->getLoader([], $theme);
$this->expectException(CoverUnavailable::class);
$loader = $this->getLoader();
$loader->getImage();
}

/**
* Test that requesting a blank QR code returns the fail image.
* Test that requesting a blank QR code results in an exception.
*
* @return void
*/
public function testDefaultLoadingForBlankText()
public function testExceptionLoadingForBlankText()
{
$this->expectException(CoverUnavailable::class);
$loader = $this->getLoader();
$loader->loadQRCode('');
}

/**
* Test that requesting a too small image results in an exception.
*
* @return void
*/
public function testExceptionForTooSmallImage()
{
$this->expectException(CoverUnavailable::class);
$loader = $this->getLoader();
$loader->loadQRCode('foofoofoofoofoofoofoofoofoofoofoofoo', ['size' => 1]);
}

/**
* Test that requesting a blank QR code returns the fail image if configured.
*
* @return void
*/
public function testDefaultLoadingForBlankText()
{
$cfg = ['QRCode' => ['noQRCodeAvailableImage' => 'images/noQRCode.gif']];
$loader = $this->getLoader($cfg);
$loader->loadQRCode('');
$this->assertEquals('image/gif', $loader->getContentType());
$this->assertEquals('483', strlen($loader->getImage()));
}

/**
* Test that requesting a too small image returns the fail image.
* Test that requesting a too small image returns the fail image if configured.
*
* @return void
*/
public function testDefaultLoadingForTooSmallImage()
{
$loader = $this->getLoader();
$cfg = ['QRCode' => ['noQRCodeAvailableImage' => 'images/noQRCode.gif']];
$loader = $this->getLoader($cfg);
$loader->loadQRCode('foofoofoofoofoofoofoofoofoofoofoofoo', ['size' => 1]);
$this->assertEquals('image/gif', $loader->getContentType());
$this->assertEquals('483', strlen($loader->getImage()));
Expand Down
2 changes: 1 addition & 1 deletion themes/bootstrap3/css/compiled.css

Large diffs are not rendered by default.

Loading
Loading