1.5 - Sacred Passage
+ * Fixed global search in navigation.
+ * Added google books parser. See upgrade file for more infos.
1.4 - Depths Of Rrajigar 2022-12-18
* Added new default sort direction field in collection edit view. See upgrade file for more needed details
+* central user-agent and browser info in config. Remove from tools
* i18n support
* Automatic upgrades of DB
* drop in updates
Each collection can have additional tools. The availability is configured in collection management.
-A tool needs an DB entry in _tool and matching files in view/THEME/tool/.
+A tool needs an DB entry in _tool and matching files in view/THEME/tool/. Best is to copy an entry
+and change name, description and action. The other settings can be left as they are, unless you know what they do.
Filenames are tool-ACTION.html|php
A optional configuration file config/config-ACTION.php
A documentation is a must.
+++ /dev/null
-# Copy the following directories and files to your installation folder, overriding the existing ones:
-webclient/config/
-webclient/lib/
-webclient/view/
-webclient/.htaccess
-webclient/api.php
-webclient/index.php
-
-# New syntax in config files
-"define(.." syntax needs to be replace with "const" syntax in all the config files.
-See the default ones about the changes.
-
-# DB changes. Run each line against your bibliotheca DB.
-# Replace #REPLACEME# with your table prefix. Default is bib
-ALTER TABLE `#REPLACEME#_collection` ADD `defaultSortOrder` VARCHAR(4) NOT NULL AFTER `defaultSortField`;
-ALTER TABLE `#REPLACEME#_menu` ADD `contextaction` VARCHAR(64) NOT NULL AFTER `action`;
-UPDATE `#REPLACEME#_menu` SET `contextaction` = 'collection' WHERE `#REPLACEME#_menu`.`id` = 4;
-UPDATE `#REPLACEME#_menu` SET `contextaction` = 'collection' WHERE `#REPLACEME#_menu`.`id` = 6;
--- /dev/null
+# Copy the following directories and files to your installation folder, overriding the existing ones:
+webclient/config/
+webclient/lib/
+webclient/view/
+webclient/.htaccess
+webclient/api.php
+webclient/index.php
+
+# New syntax in config files
+"define(.." syntax needs to be replace with "const" syntax in all the config files.
+See the default ones about the changes.
+
+# DB changes. Run each line against your bibliotheca DB.
+# Replace #REPLACEME# with your table prefix. Default is bib
+ALTER TABLE `#REPLACEME#_collection` ADD `defaultSortOrder` VARCHAR(4) NOT NULL AFTER `defaultSortField`;
+ALTER TABLE `#REPLACEME#_menu` ADD `contextaction` VARCHAR(64) NOT NULL AFTER `action`;
+UPDATE `#REPLACEME#_menu` SET `contextaction` = 'collection' WHERE `#REPLACEME#_menu`.`id` = 4;
+UPDATE `#REPLACEME#_menu` SET `contextaction` = 'collection' WHERE `#REPLACEME#_menu`.`id` = 6;
--- /dev/null
+# Copy the following directories and files to your installation folder matching the correct path.
+webclient/view/default/tool/tool-googlebooks.html
+webclient/view/default/tool/tool-googlebooks.php
+webclient/lib/googlebookparser.class.php
+webclient/config/config-googlebooks.php.default -> also copy and rename to config-googlebooks.php
+
+# DB changes. Run each line against your bibliotheca DB.
+# Replace #REPLACEME# with your table prefix. Default is bib
+INSERT INTO `#REPLACEME#_tool` (`id`, `name`, `description`, `action`, `target`, `owner`, `group`, `rights`) VALUES (NULL, 'Google Books', 'Book infos from Google', 'googlebooks', '_self', '1', '1', 'rw-r--r--');
+UPDATE `#REPLACEME#_sys_fields` SET `createstring` = '`isbn` varchar(32) NULL, ADD INDEX (`isbn`)', `apiinfo` = 'varchar 32' WHERE `#REPLACEME#_sys_fields`.`identifier` = 'isbn';
+UPDATE `#REPLACEME#_sys_fields` SET `type` = 'text', `searchtype` = 'entrySingleText' WHERE `#REPLACEME#_sys_fields`.`identifier` = 'isbn';
+
+# if you use the field ISBN already run this and change the collection id
+ALTER TABLE `#REPLACEME#_collection_entry_#CHANGE_ID#` CHANGE `isbn` `isbn` VARCHAR(32) NULL DEFAULT NULL;
--- /dev/null
+<?php
+/**
+ * Bibliotheca
+ *
+ * Copyright 2018-2023 Johannes Keßler
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Options for the Googlebook class
+ *
+ * TOOL_GOOGLEBOOKS_FIELDS_TO is a array to define which fields should be saved into
+ * a bibliotheca field. Those or the fields a collection can have. Use the identifier of a field.
+ * Depends on your settings so make sure everything is setup first. Leave it commented if not needed.
+ * nameFromService or class => bibFieldName
+ * TOOL_GOOGLEBOOKS_BROWSER_AGENT a current browser agent string. Should be updated from time to time. See default config file.
+ * TOOL_GOOGLEBOOKS_BROWSER_ACCEPT A string what the browser does accept. Should be updated from time to time. See default config file.
+ * TOOL_GOOGLEBOOKS_BROWSER_ACCEPT_LANG should define in which language the content returns
+ */
+
+const TOOL_GOOGLEBOOKS_BROWSER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0';
+const TOOL_GOOGLEBOOKS_BROWSER_ACCEPT = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
+const TOOL_GOOGLEBOOKS_BROWSER_ACCEPT_LANG = 'en-US,en;q=0.5';
+
+const TOOL_GOOGLEBOOKS_FIELDS_TO = array(
+ 'title' => 'title',
+ 'cover' => 'coverimage',
+ 'description' => 'content',
+ 'subtitle' => 'description',
+ 'isbn' => 'isbn',
+ 'authors' => 'writers',
+ 'publisher' => 'publisher',
+ 'publishedDate' => 'year',
+ 'categories' => 'genres'
+);
/**
* Bibliotheca
*
- * Copyright 2018-2021 Johannes Keßler
+ * Copyright 2018-2023 Johannes Keßler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* TOOL_IMDBWEB_FIELDS_TO is a array to define which imdbwebfield (see TOOL_IMDBWEB_FIELDS) should be saved into
* a bibliotheca field. Those or the fields a collection can have. Use the identifier of a field.
* Depends on your settings so make sure everything is setup first. Leave it commented if not needed.
+ * nameFromService => bibFieldName
* TOOL_IMDBWEB_BROWSERSTRING a current browser agent string. Should be updated from time to time. See default config file.
* TOOL_IMDBWEB_BROWSER_ACCEPT_LANG should define in which language the content returns
*/
-const = TOOL_IMDBWEB_SEARCH = 'movie';
-const = TOOL_IMDBWEB_FIELDS =
- array(
- 'getCast = 'getDescription = 'getDirector = 'getGenre = 'getPlot = 'getRating = 'getRuntime = 'getTitle =
- 'getWriter = 'getYear'
- )
-;
+const TOOL_IMDBWEB_SEARCH = 'movie';
+const TOOL_IMDBWEB_FIELDS = array(
+ 'getCast', 'getDescription', 'getDirector', 'getGenre', 'getPlot', 'getRating', 'getRuntime', 'getTitle',
+ 'getWriter', 'getYear'
+);
/*
-const = TOOL_IMDBWEB_FIELDS_TO =
- array(
- 'getCast' => 'actors = 'getDescription' => 'description = 'getDirector' => 'directors = 'getGenre' => 'genres =
- 'getPlot' => 'content = 'getRating' => 'imdbrating = 'getRuntime' => 'runtime = 'getTitle' => 'title =
- 'getWriter' => 'writers = 'getYear' => 'year'
- )
-;
+const TOOL_IMDBWEB_FIELDS_TO = array(
+ 'getCast' => 'actors', 'getDescription' => 'description', 'getDirector' => 'directors', 'getGenre' => 'genres',
+ 'getPlot' => 'content', 'getRating' => 'imdbrating', 'getRuntime' => 'runtime', 'getTitle' => 'title',
+ 'getWriter' => 'writers', 'getYear' => 'year'
+);
*/
-const = TOOL_IMDBWEB_BROWSER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0';
-const = TOOL_IMDBWEB_BROWSER_ACCEPT = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
-const = TOOL_IMDBWEB_BROWSER_ACCEPT_LANG = 'en-US,en;q=0.5';
+const TOOL_IMDBWEB_BROWSER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0';
+const TOOL_IMDBWEB_BROWSER_ACCEPT = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
+const TOOL_IMDBWEB_BROWSER_ACCEPT_LANG = 'en-US,en;q=0.5';
/**
* Bibliotheca
*
- * Copyright 2018-2021 Johannes Keßler
+ * Copyright 2018-2023 Johannes Keßler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/**
* Options for the musicbrainz class
-
- * Currently available fields are:
- * album,date,artist,tracks,image,runtime
+ *
* TOOL_BRAINZ_FIELDS_TO is a array to define which fields should be saved into
* a bibliotheca field. Those or the fields a collection can have. Use the identifier of a field.
* Depends on your settings so make sure everything is setup first. Leave it commented if not needed.
+ * nameFromService => bibFieldName
* TOOL_BRAINZ_BROWSER_AGENT a current browser agent string. Should be updated from time to time. See default config file.
* TOOL_BRAINZ_BROWSER_ACCEPT A string what the browser does accept. Should be updated from time to time. See default config file.
* TOOL_BRAINZ_BROWSER_ACCEPT_LANG should define in which language the content returns
* TOOL_BRAINZ_RESULT_LIMIT How many entries the search will display
*/
-const = TOOL_BRAINZ_BROWSER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0';
-const = TOOL_BRAINZ_BROWSER_ACCEPT = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
-const = TOOL_BRAINZ_BROWSER_ACCEPT_LANG = 'en-US,en;q=0.5';
+const TOOL_BRAINZ_BROWSER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0';
+const TOOL_BRAINZ_BROWSER_ACCEPT = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
+const TOOL_BRAINZ_BROWSER_ACCEPT_LANG = 'en-US,en;q=0.5';
-const = TOOL_BRAINZ_RESULT_LIMIT = 10;
+const TOOL_BRAINZ_RESULT_LIMIT = 10;
/*
-const = TOOL_BRAINZ_FIELDS_TO =
- array(
- 'album' => 'title = 'date' => 'year = 'artist' => 'artist = 'image' => 'coverimage = 'tracks' => 'content =
- 'runtime' => 'runtime'
- )
-;
+const TOOL_BRAINZ_FIELDS_TO = array(
+ 'album' => 'title',
+ 'date' => 'year',
+ 'artist' => 'artist',
+ 'image' => 'coverimage',
+ 'tracks' => 'content',
+ 'runtime' => 'runtime'
+);
*/
--- /dev/null
+<?php
+/**
+ * Bibliotheca
+ *
+ * Copyright 2018-2023 Johannes Keßler
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Class GoogleBooks
+ *
+ * Search for book information with google books
+ *
+ * https://developers.google.com/books/docs/overview
+ *
+ * possible alternative if google does limit the access: https://openlibrary.org/dev/docs/api/books
+ */
+class GoogleBooks {
+
+ /**
+ * @var String The google api endpoint
+ */
+ private string $_VOLUMES_ENDPOINT = 'https://www.googleapis.com/books/v1/volumes';
+
+ /**
+ * @var bool DEBUG
+ */
+ private bool $_DEBUG = false;
+
+ /**
+ * @var string The user agent used to make curl calls
+ */
+ private string $_BROWSER_AGENT = '';
+
+ /**
+ * @var string The user agent lang used to make curl calls
+ */
+ private string $_BROWSER_LANG = '';
+
+ /**
+ * @var string The user agent accept used to make curl calls
+ */
+ private string $_BROWSER_ACCEPT = '';
+
+ public function __construct(array $options) {
+ if(isset($options['debug']) && !empty($options['debug'])) {
+ $this->_DEBUG = true;
+ }
+
+ $this->_BROWSER_AGENT = $options['browserAgent'];
+ $this->_BROWSER_LANG = $options['browserLang'];
+ $this->_BROWSER_ACCEPT = $options['browserAccept'];
+ }
+
+ /**
+ * Use a given ISBN and query the google books API with it.
+ * https://developers.google.com/books/docs/overview
+ * for example: https://www.googleapis.com/books/v1/volumes?q=isbn:9780812972153
+ */
+ public function searchForISBN(string $isbn) : array {
+ $data = array();
+
+ if(!empty($isbn)) {
+ $isbn = urlencode($isbn);
+ $url = $this->_VOLUMES_ENDPOINT;
+ $url .= '?q=isbn:'.$isbn;
+
+ if(DEBUG) error_log("[DEBUG] ".__METHOD__." isbn query url: $url");
+
+ $do = $this->_curlCall($url);
+ if(!empty($do)) {
+ $data = json_decode($do, true);
+ if(!empty($data)) {
+ if(DEBUG) error_log("[DEBUG] ".__METHOD__." isbn json data:".var_export($data,true));
+ $data = $this->_buildDataFromISBNsearch($data);
+ }
+ else {
+ error_log("[ERROR] ".__METHOD__." invalid isbn json data:".var_export($do,true));
+ }
+ }
+
+ }
+
+ return $data;
+ }
+
+ /**
+ * Download given URL to a tmp file
+ * make sure to remove the tmp file after use
+ *
+ * @param string $url
+ * @return string
+ */
+ public function downloadCover(string $url): string {
+ $ret = '';
+
+ // replace zoom=1 with zoom=0 or even remove to get the full picture
+ // http://books.google.com/books/content?id=yyaxyKjyp2YC&printsec=frontcover&img=1&zoom=1&source=gbs_api
+
+ $url = str_replace("zoom=1", "zoom=0",$url);
+
+ $_tmpFile = tempnam(sys_get_temp_dir(), "bibliotheca-");
+ $fh = fopen($_tmpFile,"w+");
+ if($this->_DEBUG) {
+ error_log('[DEBUG] '.__METHOD__.' url '.var_export($url,true));
+ }
+
+ if($fh !== false) {
+
+ // modified curl call for fetching an image
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_FILE, $fh);
+
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
+ curl_setopt($ch, CURLOPT_USERAGENT, $this->_BROWSER_AGENT);
+
+ curl_exec($ch);
+ curl_close($ch);
+
+ $ret = $_tmpFile;
+ }
+ fclose($fh);
+
+ return $ret;
+ }
+
+ /**
+ * Use the given isb search data and build a nice return array
+ * Since the search is for a isbn, there should be only one result
+ *
+ * @param array $rawData
+ * @return array
+ */
+ private function _buildDataFromISBNsearch(array $rawData) : array {
+ $data = array();
+
+ if(!empty($rawData) && isset($rawData['items'][0]['volumeInfo'])) {
+ $_d = $rawData['items'][0]['volumeInfo'];
+
+ $data['title'] = $_d['title'] ?? '';
+ $data['subtitle'] = $_d['subtitle'] ?? '';
+ $data['publisher'] = $_d['publisher'] ?? '';
+ $data['publishedDate'] = $_d['publishedDate'] ?? '';
+ $data['description'] = $_d['description'] ?? '';
+ $data['authors'] = isset($_d['authors']) ? implode(",", $_d['authors']) : '';
+ $data['categories'] = isset($_d['categories']) ? implode(",", $_d['categories']) : '';
+ $data['cover'] = $_d['imageLinks']['thumbnail'] ?? '';
+
+ $data['isbn'] = '';
+ if(isset($_d['industryIdentifiers']) && is_array($_d['industryIdentifiers'])) {
+ foreach($_d['industryIdentifiers'] as $k=>$v) {
+ if($v['type'] == "ISBN_13") {
+ $data['isbn'] = $v['identifier'];
+ }
+ }
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * execute a curl call to the given $url
+ *
+ * @param string $url The request url
+ * @return string
+ */
+ private function _curlCall(string $url): string {
+ $ret = '';
+
+ $ch = curl_init();
+
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
+ curl_setopt($ch, CURLOPT_USERAGENT, $this->_BROWSER_AGENT);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array(
+ 'Accept: '.$this->_BROWSER_ACCEPT,
+ 'Accept-Language: '.$this->_BROWSER_LANG)
+ );
+
+ $_headers = array();
+ if($this->_DEBUG) {
+ curl_setopt($ch, CURLOPT_VERBOSE, true);
+
+ curl_setopt($ch, CURLOPT_HEADERFUNCTION,
+ function($curl, $header) use (&$_headers) {
+ $len = strlen($header);
+ $header = explode(':', $header, 2);
+ if (count($header) < 2) { // ignore invalid headers
+ return $len;
+ }
+ $_headers[strtolower(trim($header[0]))][] = trim($header[1]);
+ return $len;
+ }
+ );
+ }
+
+ $do = curl_exec($ch);
+ if(is_string($do) === true) {
+ $ret = $do;
+ }
+ curl_close($ch);
+
+ if($this->_DEBUG) {
+ error_log('[DEBUG] '.__METHOD__.' headers '.var_export($_headers,true));
+ }
+
+ return $ret;
+ }
+
+}
foreach($data['media'] as $media) {
foreach($media['tracks'] as $track) {
$ret['runtime'] += $track['length'];
- $l = $track['length'] / 1000;
+ $l = (int) round($track['length'] / 1000);
$l = date("i:s",$l);
$ret['tracks'] .= $track['number'].' - '.$track['title'].' - '.$l."\n";
}
* execute a curl call to the given $url
*
* @param string $url The request url
- * @param integer $port
* @return string
*/
- private function _curlCall(string $url, int $port=80): string {
+ private function _curlCall(string $url): string {
$ret = '';
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
- curl_setopt($ch, CURLOPT_PORT, $port);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
curl_setopt($ch, CURLOPT_USERAGENT, $this->_BROWSER_AGENT);
(30, 'sysReq', 'System Requirements', 'text3', 'entryText', '`sysReq` varchar(255) NULL DEFAULT NULL, ADD FULLTEXT (`sysReq`)', '', NULL, 'string 255', '2021-04-25 21:21:54', '2021-04-25 21:21:54', 0, 1, 1, 'rw-r--r--'),
(31, 'artist', 'Artist', 'text', 'entrySingleText', '`artist` varchar(128) NULL DEFAULT NULL', '', NULL, 'string 128', '2021-07-09 08:30:11', '2021-07-09 08:38:33', NULL, 1, 1, 'rw-r--r--'),
(32, 'artists', 'Artists', 'lookupmultiple', 'tag', NULL, 'allowSpace', NULL, 'string 64', '2021-07-18 11:19:03', '2021-07-18 11:19:03', NULL, 1, 1, 'rw-r--r--'),
-(33, 'isbn', 'ISBN', 'number', 'entrySingleNum', '`isbn` int(10) NULL, ADD INDEX (`isbn`)', '', NULL, 'int 10', '2022-10-03 09:26:53', '2022-10-03 09:26:53', NULL, 1, 1, 'rw-r--r--');
+(33, 'isbn', 'ISBN', 'text', 'entrySingleText', '`isbn` varchar(32) NULL, ADD INDEX (`isbn`)', '', NULL, 'varchar 32', '2022-10-03 09:26:53', '2022-10-03 09:26:53', NULL, 1, 1, 'rw-r--r--');
-- --------------------------------------------------------
(1, 'IMDB web', 'Web parser', 'imdbweb', '_self', 1, 1, 'rw-r--r--'),
(2, 'Game infos', 'Game infos', 'gameinfo', '_self', 1, 1, 'rw-r--r--'),
(3, 'Musicbrainz', 'Album infos', 'musicbrainz', '_self', 1, 1, 'rw-r--r--');
+(4, 'Google Books', 'Book infos from Google', 'googlebooks', '_self', 1, 1, 'rw-r--r--');
-- --------------------------------------------------------
--- /dev/null
+<p><b>Limitations</b></p>
+<p>Data will be overwritten</p>
+
+<form class="uk-form-horizontal uk-margin-small" method="post" enctype="multipart/form-data">
+ <div class="uk-margin">
+ <label class="uk-form-label" for="search">Search ISBN</label>
+ <div class="uk-form-controls">
+ <input class="uk-input" id="search" type="text" autocomplete="off"
+ name="fdata[search]"
+ value="<?php echo Summoner::ifset($TemplateData['editEntry'], 'isbn'); ?>"
+ >
+ </div>
+ <div class="uk-margin">
+ <button class="uk-button uk-button-primary" type="submit" name="submitFormSearch">
+ Search
+ </button>
+ </div>
+ </div>
+</form>
+
+<?php if($TemplateData['showMatchingForm']) { ?>
+<form class="uk-form-horizontal uk-margin-small uk-grid-small"
+ method="post" enctype="multipart/form-data" uk-grid>
+
+ <?php
+ if(!empty($TemplateData['bookData'])) {
+ foreach($TemplateData['bookData'] as $k=>$v) {
+ ?>
+ <input name="fdata[from][<?php echo $k; ?>]" type="hidden" value="<?php echo $v; ?>" />
+ <div class="uk-width-1-2@s uk-overflow-hidden">
+ <p>
+ <b><?php echo $k; ?></b><br />
+ <?php echo nl2br($v); ?>
+ </p>
+ </div>
+ <div class="uk-width-1-2@s">
+ <select class="uk-select" name="fdata[into][<?php echo $k; ?>]">
+ <option value="">None</option>
+ <?php echo toolMethod_GetTargetSelection($TemplateData['saveToSelection'],$k); ?>
+ </select>
+ </div>
+
+ <?php
+ }
+ }
+ ?>
+
+ <div class="uk-margin">
+ <button class="uk-button uk-button-primary" type="submit" name="submitFormSave">
+ Save
+ </button>
+ </div>
+
+</form>
+<?php } ?>
--- /dev/null
+<?php
+/**
+ * Bibliotheca
+ *
+ * Copyright 2018-2023 Johannes Keßler
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * this is the special file for a tool.
+ * Requirements and more information come from the main tool.php file
+ */
+
+require_once 'lib/googlebookparser.class.php';
+if(file_exists(PATH_ABSOLUTE.'/config/config-googlebooks.php')) {
+ require_once 'config/config-googlebooks.php';
+}
+
+$GOOGLEBOOKS = new GoogleBooks(array(
+ 'browserAgent' => TOOL_GOOGLEBOOKS_BROWSER_AGENT,
+ 'browserLang' => TOOL_GOOGLEBOOKS_BROWSER_ACCEPT_LANG,
+ 'browserAccept' => TOOL_GOOGLEBOOKS_BROWSER_ACCEPT,
+ 'debug' => true
+));
+
+$TemplateData['bookData'] = array();
+$TemplateData['saveToSelection'] = '';
+$TemplateData['showMatchingForm'] = false;
+
+// prepare fields to save into selection
+// create one time and then reuse it
+$collectionFields = $ManangeCollectionsFields->getExistingFields(false, true);
+if(!empty($collectionFields)) {
+ foreach ($collectionFields as $k=>$v) {
+ $TemplateData['saveToSelection'] .= "<option value='".$k."' sel_".$v['identifier'].">".$v['displayname']."</option>\n";
+ }
+}
+
+if(isset($_POST['submitFormSearch'])) {
+ $fdata = $_POST['fdata'];
+ if (!empty($fdata)) {
+ $search = trim($fdata['search']);
+ $search = Summoner::validate($search) ? $search : false;
+
+ if(!empty($search)) {
+ $booksearch = $GOOGLEBOOKS->searchForISBN($search);
+
+ if(!empty($booksearch)) {
+ $TemplateData['bookData'] = $booksearch;
+ $TemplateData['showMatchingForm'] = true;
+ } else {
+ $TemplateData['message']['content'] = "Nothing found.";
+ $TemplateData['message']['status'] = "error";
+ }
+ }
+ else {
+ $TemplateData['message']['content'] = "Invalid search term";
+ $TemplateData['message']['status'] = "error";
+ }
+ }
+}
+
+if(isset($_POST['submitFormSave'])) {
+ $fdata = $_POST['fdata'];
+ if (!empty($fdata)) {
+
+ // build data array based on submit
+ // see creation log for structure
+ $_data = array();
+ foreach($fdata['into'] as $k=>$v) {
+ if(!empty($v) && isset($fdata['from'][$k])) {
+ if(isset($collectionFields[$v])) {
+
+ $_data[$v] = $collectionFields[$v];
+ $_data[$v]['valueToSave'] = $fdata['from'][$k];
+
+ // special case for image
+ if($k == "cover") {
+
+ $fieldData = array();
+
+ $_f = $GOOGLEBOOKS->downloadCover($fdata['from'][$k]);
+ if($_f && is_file($_f)) {
+ $_e = UPLOAD_ERR_OK;
+ // build _FILES based on regular add form
+ $fieldData['name'][$_data[$v]['identifier']] = 'cover.jpg';
+ $fieldData['type'][$_data[$v]['identifier']] = mime_content_type($_f);
+ $fieldData['size'][$_data[$v]['identifier']] = filesize($_f);
+ $fieldData['tmp_name'][$_data[$v]['identifier']] = $_f;
+ $fieldData['error'][$_data[$v]['identifier']] = UPLOAD_ERR_OK;
+ $fieldData['rebuildUpload'][$_data[$v]['identifier']] = true;
+ }
+
+ $_data[$v]['uploadData'] = $fieldData;
+ }
+ }
+ }
+ }
+
+ $_r = $Tools->getDefaultCreationInfo();
+ if(!empty($TemplateData['editEntry'])) {
+ // update existing one
+ $do = $Manageentry->create($_data,
+ $_r['id'],
+ $_r['group'],
+ $_r['rights'],
+ $TemplateData['editEntry']['id']
+ );
+ $TemplateData['message']['content'] = "Date saved successfully";
+ }
+ else {
+ // create into loaded collection
+ $do = $Manageentry->create($_data,
+ $_r['id'],
+ $_r['group'],
+ $_r['rights']
+ );
+ $TemplateData['message']['content'] = "Date saved successfully:
+ <a href='index.php?p=manageentry&collection=".$collection['id']."&id=".$do."'>Here</a>";
+ }
+
+ if(!empty($do)) {
+ $TemplateData['message']['status'] = "success";
+ }
+ else {
+ $TemplateData['message']['content'] = "Data could not be saved. See logs for more.";
+ $TemplateData['message']['status'] = "error";
+ }
+
+ // remove tmp file
+ if(isset($_f) && is_file($_f) && file_exists($_f)) {
+ unlink($_f);
+ }
+ }
+}
+
+
+/**
+ * Helper function. Takes the prebuild options for the target selection field and search for a matching key.
+ * Since the optionString is prebuild, avoiding looping over and over again, the selection needs to be done
+ * by search and replace.
+ * Checks if TOOL_GOOGLEBOOKS_FIELDS_TO is defined and a matching key=>value pair is available
+ *
+ * @param string $optionString
+ * @param string $googleKey
+ * @return string
+ */
+function toolMethod_GetTargetSelection(string $optionString, string $googleKey): string {
+ if(defined('TOOL_GOOGLEBOOKS_FIELDS_TO') & !empty($googleKey)) {
+ if(isset(TOOL_GOOGLEBOOKS_FIELDS_TO[$googleKey])) {
+ $_k = "sel_".TOOL_GOOGLEBOOKS_FIELDS_TO[$googleKey];
+ $optionString = str_replace($_k,'selected="selected"',$optionString);
+ }
+ }
+
+ return $optionString;
+}
/**
* Bibliotheca
*
- * Copyright 2018-2021 Johannes Keßler
+ * Copyright 2018-2023 Johannes Keßler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
'browserAgent' => TOOL_BRAINZ_BROWSER_AGENT,
'browserLang' => TOOL_BRAINZ_BROWSER_ACCEPT_LANG,
'browserAccept' => TOOL_BRAINZ_BROWSER_ACCEPT,
- 'debug' => true
+ 'debug' => false
));
$TemplateData['releases'] = array();
$TemplateData['message']['content'] = "Data could not be saved. See logs for more.";
$TemplateData['message']['status'] = "error";
}
+
+ // remove tmp file
+ if(isset($_f) && is_file($_f) && file_exists($_f)) {
+ unlink($_f);
+ }
}
}