diff --git a/config/vufind/config.ini b/config/vufind/config.ini index 71b5906e03a7ae33b1810f34b368fb03931d90c8..e951a96e6f7f14fa085521a552c3a1ff0ed8d2bb 100644 --- a/config/vufind/config.ini +++ b/config/vufind/config.ini @@ -627,9 +627,26 @@ database = mysql://root@localhost/vufind ;coversize = false ; You can select Syndetics, LibraryThing, Summon, Amazon, Booksite, OpenLibrary, -; Contentcafe, Buchhandel.de and/or Google Books. +; Contentcafe, Buchhandel.de, Google Books, and/or LocalFile. ; Note: Summon service takes a Serials Solutions client key, NOT Summon API key! -;coverimages = Syndetics:MySyndeticsId,Amazon:MyAccessKeyId,Booksite,LibraryThing:MyLibraryThingId,Google,OpenLibrary,Summon:MySerialsSolutionsClientKey,Contentcafe:MyContentCafeID +; 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,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 diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index 28daf7cf626083b7f054d5f6c30c912531583f08..6c9668bbcf7afc6ab4bb3e997268e295f3550e14 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -372,6 +372,7 @@ $config = [ 'invokables' => [ 'google' => 'VuFind\Content\Covers\Google', 'librarything' => 'VuFind\Content\Covers\LibraryThing', + 'localfile' => 'VuFind\Content\Covers\LocalFile', 'openlibrary' => 'VuFind\Content\Covers\OpenLibrary', 'summon' => 'VuFind\Content\Covers\Summon', ], diff --git a/module/VuFind/src/VuFind/Content/Covers/LocalFile.php b/module/VuFind/src/VuFind/Content/Covers/LocalFile.php new file mode 100644 index 0000000000000000000000000000000000000000..94d5c30e5b89bc16a4b0b7f890f555fd73cb2de5 --- /dev/null +++ b/module/VuFind/src/VuFind/Content/Covers/LocalFile.php @@ -0,0 +1,155 @@ +<?php +/** + * LocalFile cover content loader. + * + * PHP version 5 + * + * 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 Leila Gonzales <lmg@agiweb.org> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\Content\Covers; + +/** + * Local file cover content loader. + * + * @category VuFind + * @package Content + * @author Leila Gonzales <lmg@agiweb.org> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class LocalFile extends \VuFind\Content\AbstractCover +{ + /** + * Image file extensions to look for when using %anyimage% token. + * + * @var array + */ + protected $imageExtensions = ["gif", "jpg", "jpeg", "png", "tif", "tiff"]; + + /** + * MIME types allowed to be loaded from disk. + * + * @var array + */ + protected $allowedMimeTypes = [ + "image/gif", "image/jpeg", "image/png", "image/tiff" + ]; + + /** + * Does this plugin support the provided ID array? + * + * @param array $ids IDs that will later be sent to load() -- see below. + * + * @return bool + */ + public function supports($ids) + { + // We won't know what we need until we parse the path string; accept + // everything at this stage: + return true; + } + + /** + * Get image location from local file storage. + * + * @param string $key local file directory path + * @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) + { + // convert all of the tokens: + $fileName = $this->replaceImageTypeTokens( + $this->replaceEnvironmentAndIdTokens($key, $ids) + ); + // Validate MIME type if we have a valid file path. + if ($fileName && file_exists($fileName)) { + if (in_array(mime_content_type($fileName), $this->allowedMimeTypes)) { + return "file://" . $fileName; + } + } + // If we got this far, we couldn't find a match. + return false; + } + + /** + * Convert tokens to ids array values. + * + * @param string $filePath file path of image file + * @param array $ids Associative array of identifiers + * (keys may include 'isbn' pointing to an ISBN object and + * 'issn' pointing to a string) + * + * @return string + */ + protected function replaceEnvironmentAndIdTokens($filePath, $ids) + { + // Seed the token array with standard environment variables: + $tokens = ['%vufind-home%', '%vufind-local-dir%']; + $replacements = [APPLICATION_PATH, LOCAL_OVERRIDE_DIR]; + + // Only create tokens for strings, not objects: + foreach ($ids as $key => $val) { + if (is_string($val)) { + $tokens[] = '%' . $key . '%'; + $replacements[] = $val; + } + } + // Special-case handling for ISBN object: + if (isset($ids['isbn'])) { + $tokens[] = '%isbn10%'; + $replacements[] = $ids['isbn']->get10(); + + $tokens[] = '%isbn13%'; + $replacements[] = $ids['isbn']->get13(); + } + return str_replace($tokens, $replacements, $filePath); + } + + /** + * Convert tokens to image type file extension. + * + * @param string $fileName file path of image file + * + * @return bool|string + */ + protected function replaceImageTypeTokens($fileName) + { + // If anyimage is specified, then we loop through all + // image extensions to find the right filename + if (strstr($fileName, '%anyimage%')) { + foreach ($this->imageExtensions as $val) { + foreach ([$val, strtoupper($val), ucwords($val)] as $finalVal) { + $checkFile = str_replace('%anyimage%', $finalVal, $fileName); + if (file_exists($checkFile)) { + return $checkFile; + } + } + } + } + // Default behavior: do not modify filename: + return $fileName; + } +} diff --git a/module/VuFind/src/VuFind/Controller/CoverController.php b/module/VuFind/src/VuFind/Controller/CoverController.php index 9c387fb605c88e9f8f900f95670c91cc0d2d6b37..9284ca2b3e32bf4f5702560b8f22041f8b0d8ae1 100644 --- a/module/VuFind/src/VuFind/Controller/CoverController.php +++ b/module/VuFind/src/VuFind/Controller/CoverController.php @@ -125,6 +125,8 @@ class CoverController extends AbstractBase 'issn' => $params()->fromQuery('issn'), 'oclc' => $params()->fromQuery('oclc'), 'upc' => $params()->fromQuery('upc'), + 'recordid' => $params()->fromQuery('recordid'), + 'source' => $params()->fromQuery('source'), ]; } diff --git a/module/VuFind/src/VuFind/Cover/Loader.php b/module/VuFind/src/VuFind/Cover/Loader.php index 28c4477cb7dfc8f42aedee3d345ad58187492cc9..b48675e37acc770538c9e7941a5d794017f6d723 100644 --- a/module/VuFind/src/VuFind/Cover/Loader.php +++ b/module/VuFind/src/VuFind/Cover/Loader.php @@ -111,6 +111,20 @@ class Loader extends \VuFind\ImageLoader */ protected $upc = null; + /** + * User record id number parameter + * + * @var string + */ + protected $recordid = null; + + /** + * User record source parameter + * + * @var string + */ + protected $source = null; + /** * User size parameter * @@ -209,6 +223,8 @@ class Loader extends \VuFind\ImageLoader 'issn' => null, 'oclc' => null, 'upc' => null, + 'recordid' => null, + 'source' => null, ]; } @@ -253,6 +269,8 @@ class Loader extends \VuFind\ImageLoader } $this->oclc = $settings['oclc']; $this->upc = $settings['upc']; + $this->recordid = $settings['recordid']; + $this->source = $settings['source']; $this->type = preg_replace('/[^a-zA-Z]/', '', $settings['type']); $this->size = $settings['size']; } @@ -321,8 +339,13 @@ class Loader extends \VuFind\ImageLoader return $this->getCachePath($this->size, 'OCLC' . $ids['oclc']); } else if (isset($ids['upc'])) { return $this->getCachePath($this->size, 'UPC' . $ids['upc']); + } else if (isset($ids['recordid']) && isset($ids['source'])) { + return $this->getCachePath( + $this->size, + 'ID' . md5($ids['source'] . '|' . $ids['recordid']) + ); } - throw new \Exception('Unexpected code path reached!'); + throw new \Exception('Cannot determine local file path.'); } /** @@ -345,6 +368,12 @@ class Loader extends \VuFind\ImageLoader if ($this->upc && strlen($this->upc) > 0) { $ids['upc'] = $this->upc; } + if ($this->recordid && strlen($this->recordid) > 0) { + $ids['recordid'] = $this->recordid; + } + if ($this->source && strlen($this->source) > 0) { + $ids['source'] = $this->source; + } return $ids; } @@ -557,44 +586,52 @@ class Loader extends \VuFind\ImageLoader */ protected function processImageURL($url, $cache = true) { - // Attempt to pull down the image: - $result = $this->client->setUri($url)->send(); - if (!$result->isSuccess()) { - $this->debug("Failed to retrieve image from " + $url); - return false; - } + // Check to see if url is a file path + if (substr($url, 0, 7) == "file://") { + $imagePath = substr($url, 7); - $image = $result->getBody(); + // Display the image: + $this->contentType = mime_content_type($imagePath); + $this->image = file_get_contents($imagePath); + return true; + } else { + // Attempt to pull down the image: + $result = $this->client->setUri($url)->send(); + if (!$result->isSuccess()) { + $this->debug("Failed to retrieve image from " + $url); + return false; + } + $image = $result->getBody(); - if ('' == $image) { - return false; - } + if ('' == $image) { + return false; + } - // Figure out file paths -- $tempFile will be used to store the - // image for analysis. $finalFile will be used for long-term storage if - // $cache is true or for temporary display purposes if $cache is false. - $tempFile = str_replace('.jpg', uniqid(), $this->localFile); - $finalFile = $cache ? $this->localFile : $tempFile . '.jpg'; + // Figure out file paths -- $tempFile will be used to store the + // image for analysis. $finalFile will be used for long-term storage if + // $cache is true or for temporary display purposes if $cache is false. + $tempFile = str_replace('.jpg', uniqid(), $this->localFile); + $finalFile = $cache ? $this->localFile : $tempFile . '.jpg'; - // Write image data to disk: - if (!@file_put_contents($tempFile, $image)) { - throw new \Exception("Unable to write to image directory."); - } + // Write image data to disk: + if (!@file_put_contents($tempFile, $image)) { + throw new \Exception("Unable to write to image directory."); + } - // Move temporary file to final location: - if (!$this->validateAndMoveTempFile($image, $tempFile, $finalFile)) { - return false; - } + // Move temporary file to final location: + if (!$this->validateAndMoveTempFile($image, $tempFile, $finalFile)) { + return false; + } - // Display the image: - $this->contentType = 'image/jpeg'; - $this->image = file_get_contents($finalFile); + // Display the image: + $this->contentType = 'image/jpeg'; + $this->image = file_get_contents($finalFile); - // If we don't want to cache the image, delete it now that we're done. - if (!$cache) { - @unlink($finalFile); + // If we don't want to cache the image, delete it now that we're done. + if (!$cache) { + @unlink($finalFile); + } + return true; } - - return true; } } diff --git a/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php b/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php index 361f0cfe46065676a70ad77ea12ac4d52d210e12..688a6c7d5f1017e73ae306926821aa78aa207bdb 100644 --- a/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php +++ b/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php @@ -1349,7 +1349,9 @@ class SolrDefault extends AbstractBase 'author' => mb_substr($this->getPrimaryAuthor(), 0, 300, 'utf-8'), 'callnumber' => $this->getCallNumber(), 'size' => $size, - 'title' => mb_substr($this->getTitle(), 0, 300, 'utf-8') + 'title' => mb_substr($this->getTitle(), 0, 300, 'utf-8'), + 'recordid' => $this->getUniqueID(), + 'source' => $this->getSourceIdentifier(), ]; if ($isbn = $this->getCleanISBN()) { $arr['isbn'] = $isbn;