-1.x - NyLeve's Falls
+1.x - NyLeve's Falls (TBD)
+ * Updated requirements information
+ * Added Musicbrainz grabber
+ * Added new field: artist
1.1 - Vortex Rikers 20210530
* Cleanup and merge to one config file. Read upgrade
+* User friendly setup
* stats overview page. amount of entries. file / cache and db storage. Version info and where to find it.
* User and groupmanagement: Check where a user or group is used!
* Better error handling and display while adding / update and delete
easier since not every field the tool provides are needed.
Follow the comments in the file for more details.
-An option to make the target fields automatically selected by default to given values.
+An option to make the target fields automatically selected by default to given values is also available
+in the config file.
+
+# Setup
+Rename the config-imdbweb.php.default to config-imdbweb.php in the config folder.
+Follow the comments to update the settings.
--- /dev/null
+# 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, 'Musicbrainz', 'Album infos', 'musicbrainz', '_self', '1', '1', 'rw-r--r--');
+INSERT INTO `#REPLACEME#_sys_fields` (`id`, `identifier`, `displayname`, `type`, `searchtype`, `createstring`, `inputValidation`, `value`, `apiinfo`, `created`, `modified`, `modificationuser`, `owner`, `group`, `rights`) VALUES (NULL, 'artist', 'Artist', 'text', 'entrySingleText', '`artists` varchar(128) NULL DEFAULT NULL', '', NULL, 'string 128', NOW(), NOW(), NULL, '1', '1', 'rw-r--r--');
+UPDATE `#REPLACEME#_sys_fields` SET `type` = 'year' WHERE `bib_sys_fields`.`id` = 14;
<?php
+<?php
+/**
+ * Bibliotheca
+ *
+ * Copyright 2018-2021 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 grabber
+ * Options for the imdb grabber
*
* TOOL_IMDBWEB_SEARCH can be 'movie','tv','episode','game','all'. Default is movie
* TOOL_IMDBWEB_FIELDS is an array to define which fields from IMDB are displayed for selection
--- /dev/null
+<?php
+/**
+ * Bibliotheca
+ *
+ * Copyright 2018-2021 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 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.
+ * 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
+ */
+
+define('TOOL_BRAINZ_BROWSER_AGENT','Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0');
+define('TOOL_BRAINZ_BROWSER_ACCEPT','text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8');
+define('TOOL_BRAINZ_BROWSER_ACCEPT_LANG','en-US,en;q=0.5');
+
+define('TOOL_BRAINZ_RESULT_LIMIT',10);
+
+define('TOOL_BRAINZ_FIELDS_TO',
+ array(
+ 'album' => 'title','date' => 'year', 'artist' => 'artist', 'image' => 'coverimage', 'tracks' => 'content',
+ 'runtime' => 'runtime'
+ )
+);
private function _saveField_selection($data, $queryData) {
return $this->_saveField_text($data, $queryData);
}
+
/**
* Create part of the insert statement for field type year
+ * Uses some simple 4 digit patter to extract the year if the input is
+ * something like 2001-02-03
*
* @param array $data Field data
* @param array $queryData Query data array
* @return array
*/
private function _saveField_year($data, $queryData) {
+ preg_match('/[0-9]{4}/', $data['valueToSave'], $matches);
+ if(isset($matches[0]) && !empty($matches[0])) {
+ $data['valueToSave'] = $matches[0];
+ }
return $this->_saveField_number($data, $queryData);
}
private function _saveField_number($data, $queryData) {
// make sure there is something (int) to save
if(empty($data['valueToSave'])) {
- $data['valueToSave'] = 0;
+ $data['valueToSave'] = 0;
}
$data['valueToSave'] = preg_replace('/[^\p{N}]/u', '', $data['valueToSave']);
$queryData['init'][] = "`".$data['identifier']."` = '".$this->_DB->real_escape_string($data['valueToSave'])."'";
* @param array $queryData
* @return array
*/
- private function _saveField_upload($data, $queryData) {
+ private function _saveField_upload(array $data, array $queryData): array {
$_up = $data['uploadData'];
// delete the single upload
'identifier' => $data['identifier'],
'name' => $newFilename,
'tmp_name' => $_up['tmp_name'][$data['identifier']],
- 'multiple' => false
+ 'multiple' => false,
+ 'rebuildUpload' => $_up['rebuildUpload'][$data['identifier']]
);
}
return $queryData;
* @param array $queryData
* @return array
*/
- private function _saveField_upload_multiple($data, $queryData) {
+ private function _saveField_upload_multiple(array $data, array $queryData): array {
$_up = $data['uploadData'];
if(isset($data['deleteData'])) {
'identifier' => $data['identifier'],
'name' => $newFilename,
'tmp_name' => $_up['tmp_name'][$data['identifier']][$k],
- 'multiple' => true
+ 'multiple' => true,
+ 'rebuildUpload' => $_up['rebuildUpload'][$data['identifier']][$k]
);
}
}
* @param string $insertId Number
* @throws Exception
*/
- private function _runAfter_upload($uploadData, $insertId) {
+ private function _runAfter_upload(array $uploadData, string $insertId) {
if(!empty($uploadData) && !empty($insertId)) {
if(DEBUG) error_log("[DEBUG] ".__METHOD__." uploadata: ".var_export($uploadData,true));
$_path = PATH_STORAGE.'/'.$this->_collectionId.'/'.$insertId;
}
if(isset($uploadData['tmp_name']) && isset($uploadData['name'])) {
- if(!move_uploaded_file($uploadData['tmp_name'],$_path.'/'.$uploadData['identifier'].'-'.$uploadData['name'])) {
+ // special case if the image is already uploaded and not a real POST/FILES request
+ if(isset($uploadData['rebuildUpload']) && $uploadData['rebuildUpload'] === true) {
+ if(!rename($uploadData['tmp_name'],$_path.'/'.$uploadData['identifier'].'-'.$uploadData['name'])) {
+ throw new Exception("Can not rename file to: ".$_path.'/'.$uploadData['identifier'].'-'.$uploadData['name']);
+ }
+ }
+ elseif(!move_uploaded_file($uploadData['tmp_name'],$_path.'/'.$uploadData['identifier'].'-'.$uploadData['name'])) {
throw new Exception("Can not move file to: ".$_path.'/'.$uploadData['identifier'].'-'.$uploadData['name']);
}
}
* @param $data array The entry data from getEditData
* @return bool
*/
- private function _isOwner($data) {
+ private function _isOwner(array $data): bool {
$ret = false;
if($this->_User->param('isRoot')) {
--- /dev/null
+<?php
+/**
+ * Bibliotheca
+ *
+ * Copyright 2018-2021 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 Musicbrainz
+ *
+ * Simple search for an artist and album
+ *
+ * https://musicbrainz.org/doc/Development
+ * https://musicbrainz.org/doc/MusicBrainz_API/Examples
+ * https://musicbrainz.org/doc/MusicBrainz_API/Search
+ * https://musicbrainz.org/doc/MusicBrainz_API
+ */
+class Musicbrainz {
+
+ /**
+ * @var bool DEBUG
+ */
+ private $_DEBUG = false;
+
+ /**
+ * @var string The user agent used to make curl calls
+ */
+ private $_BROWSER_AGENT = '';
+
+ /**
+ * @var string The user agent lang used to make curl calls
+ */
+ private $_BROWSER_LANG = '';
+
+ /**
+ * @var string The user agent accept used to make curl calls
+ */
+ private $_BROWSER_ACCEPT = '';
+
+ /**
+ * @var string The musicbrainz API release endpoint
+ */
+ private $_RELEASE_ENDPOINT = 'http://musicbrainz.org/ws/2/release/';
+
+ /**
+ * @var string The endpoint for images
+ */
+ private $_IMAGE_ENDPOINT = 'http://coverartarchive.org/release/';
+
+ /**
+ * @var int The amount of entries returned for release search
+ */
+ private $_resultLimit = 10;
+
+ /**
+ * Musicbrainz constructor.
+ *
+ * @param $options array
+ */
+ public function __construct(array $options) {
+ if(isset($options['debug']) && !empty($options['debug'])) {
+ $this->_DEBUG = true;
+ }
+
+ if(isset($options['resultLimit']) && !empty($options['resultLimit'])) {
+ $this->_resultLimit = $options['resultLimit'];
+ }
+
+ $this->_BROWSER_AGENT = $options['browserAgent'];
+ $this->_BROWSER_LANG = $options['browserLang'];
+ $this->_BROWSER_ACCEPT = $options['browserAccept'];
+ }
+
+
+ /**
+ * Search for a release fpr the given artist and album name
+ *
+ * http://musicbrainz.org/ws/2/release/?query=artist:broilers%20AND%20release:muerte%20AND%20format:CD&fmt=json
+ *
+ * [releaseID] = title - artist - status - date - country - disambiguation - packaging - track-count
+ *
+ *
+ * @param string $artist The artist to search for
+ * @param string $album The album of the artist to search for
+ *
+ * @return array
+ */
+ public function searchForRelease(string $artist, string $album): array {
+ $ret = array();
+
+ if(!empty($artist) && !empty($album)) {
+ $artist = urlencode($artist);
+ $album = urlencode($album);
+ $url = $this->_RELEASE_ENDPOINT;
+ $url .= '?&fmt=json&limit='.$this->_resultLimit.'&query=';
+ $url .= 'artist:'.$artist.'%20AND%20release:'.$album.'%20AND%20format:CD';
+
+ if(DEBUG) error_log("[DEBUG] musicbrainz release url: $url");
+
+ $do = $this->_curlCall($url);
+ $data = '';
+ if(!empty($do)) {
+ $data = json_decode($do, true);
+ if(!empty($data)) {
+ if(DEBUG) error_log("[DEBUG] musicbrainz releases json data:".var_export($data,true));
+ }
+ else {
+ error_log("[ERROR] musicbrainz invalid releases json data:".var_export($do,true));
+ }
+ }
+
+ if(!empty($data)) {
+ if(isset($data['releases'])) {
+ foreach($data['releases'] as $release) {
+ if(isset($release['title'])
+ && isset($release['status'])
+ && isset($release['date'])
+ && isset($release['country'])
+ && isset($release['artist-credit'][0]['name'])) {
+
+ $ret[$release['id']] = $release['title'].' - '.$release['artist-credit'][0]['name'].'; '.$release['status'].'; '.$release['date'].'; '.$release['country'];
+
+ if(isset($release['disambiguation'])) {
+ $ret[$release['id']] .= '; '.$release['disambiguation'];
+ }
+ if(isset($release['packaging'])) {
+ $ret[$release['id']] .= '; '.$release['packaging'];
+ }
+
+ if(isset($release['track-count'])) {
+ $ret[$release['id']] .= '; tracks: '.$release['track-count'];
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Get the information from musicBrainz by given release ID
+ * https://musicbrainz.org/doc/MusicBrainz_API/Examples#Release
+ *
+ * http://musicbrainz.org/ws/2/release/59211ea4-ffd2-4ad9-9a4e-941d3148024a?inc=recordings&fmt=json
+ *
+ * [album] => title
+ * [date] => date
+ * [artist] => artist-credit name
+ * [tracks] => number - title - min
+ * [image] => img url
+ * [runtime] => summed up runtime in minutes from tracks
+ *
+ * @param string $releaseId
+ * @return array
+ */
+ public function getReleaseInfo(string $releaseId): array {
+ $ret = array();
+
+ if(!empty($releaseId)) {
+ $url = $this->_RELEASE_ENDPOINT;
+ $url .= $releaseId;
+ $url .= '?&fmt=json&inc=recordings+artist-credits';
+
+ $do = $this->_curlCall($url);
+ $data = '';
+ if(!empty($do)) {
+ $data = json_decode($do, true);
+ if(!empty($data)) {
+ if(DEBUG) error_log("[DEBUG] musicbrainz release json data:".var_export($data,true));
+ }
+ else {
+ error_log("[ERROR] musicbrainz invalid release json data:".var_export($do,true));
+ }
+ }
+
+ if(!empty($data)) {
+ $ret['id'] = isset($data['id']) ? $data['id'] : '';
+ $ret['album'] = isset($data['title']) ? $data['title'] : '';
+ $ret['date'] = isset($data['date']) ? $data['date'] : '';
+ $ret['artist'] = isset($data['artist-credit'][0]['name']) ? $data['artist-credit'][0]['name'] : '';
+ $ret['tracks'] = '';
+ $ret['image'] = '';
+ $ret['runtime'] = 0;
+ foreach($data['media'][0]['tracks'] as $track) {
+ $ret['runtime'] += $track['length'];
+ $l = $track['length'] / 1000;
+ $l = date("i:s",$l);
+ $ret['tracks'] .= $track['number'].' - '.$track['title'].' - '.$l."\n";
+ }
+ $ret['runtime'] = $ret['runtime'] / 1000;
+ $ret['runtime'] = date("i",$ret['runtime']);
+
+ // image
+ $do = $this->_curlCall($this->_IMAGE_ENDPOINT.$releaseId);
+ if(!empty($do)) {
+ $imageData = json_decode($do, true);
+ if(!empty($imageData)) {
+ if(DEBUG) error_log("[DEBUG] image release json data:".var_export($imageData,true));
+ $ret['image'] = isset($imageData['images'][0]['image']) ? $imageData['images'][0]['image'] : '';
+ }
+ else {
+ error_log("[ERROR] image invalid release json data:".var_export($do,true));
+ }
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
+ * 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 = '';
+
+ $_tmpFile = tempnam(sys_get_temp_dir(), "bibliotheca-");
+ $fh = fopen($_tmpFile,"w+");
+ if($fh !== false) {
+
+ $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);
+
+ 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;
+ }
+ );
+ }
+
+ curl_exec($ch);
+ curl_close($ch);
+
+ if($this->_DEBUG) {
+ error_log('[DEBUG] '.__METHOD__.' headers '.var_export($_headers,true));
+ }
+
+ $ret = $_tmpFile;
+ }
+ fclose($fh);
+
+ return $ret;
+ }
+
+ /**
+ * execute a curl call to the given $url
+ *
+ * @param string $url The request url
+ * @param integer $port
+ * @return string
+ */
+ private function _curlCall(string $url, $port=80): 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_PORT, $port);
+ 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)
+ );
+
+ 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;
+ }
+}
}
/**
- * execute a curl call to the fiven $url
- * @param string $url The request url
- * @param integer $port
- * @return bool|string
- */
- static function curlCall($url,$port=80) {
- $ret = false;
-
- $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_PORT, $port);
-
- $do = curl_exec($ch);
- if(is_string($do) === true) {
- $ret = $do;
- }
-
- curl_close($ch);
-
- return $ret;
- }
-
- /**
- * check if a string strts with a given string
+ * check if a string starts with a given string
*
* @param string $haystack
* @param string $needle
$_value = trim($fdata[$fieldData['identifier']]);
$fieldData['valueToSave'] = trim($fdata[$fieldData['identifier']]);
$_fieldsToSave[$fieldData['identifier']] = $fieldData;
- } elseif(isset($fupload['name'][$fieldData['identifier']])) {
+ } elseif(isset($fupload['name'][$fieldData['identifier']])) { // special case upload
if(isset($fdata[$fieldData['identifier']."_delete"])) {
$fieldData['deleteData'] = $fdata[$fieldData['identifier']."_delete"];
}
- // special case upload
- // $_FILES data is combined
+
+ // $_FILES data is combined if multiple
$fieldData['uploadData'] = $fupload;
$_fieldsToSave[$fieldData['identifier']] = $fieldData;
if(!empty($_imdbId)) {
try {
- $IMDB->search($_imdbId);
+ $IMDB->search($_imdbId); // cache used
}
catch (Exception $e) {
if(DEBUG) error_log("[DEBUG] imdb search catch: ".$e->getMessage());
--- /dev/null
+<form class="uk-form-horizontal uk-margin-small" method="post" enctype="multipart/form-data">
+ <div class="uk-margin">
+ <label class="uk-form-label" for="artist">Artist</label>
+ <div class="uk-form-controls">
+ <input class="uk-input" id="artist" type="text" autocomplete="off"
+ name="fdata[artist]"
+ value="<?php echo Summoner::ifset($TemplateData['editEntry'], 'artist'); ?>"
+ >
+ </div>
+ </div>
+ <div class="uk-margin">
+ <label class="uk-form-label" for="album">Album/Title</label>
+ <div class="uk-form-controls">
+ <input class="uk-input" id="album" type="text" autocomplete="off"
+ name="fdata[album]"
+ value="<?php echo Summoner::ifset($TemplateData['editEntry'], 'title'); ?>"
+ >
+ </div>
+ </div>
+ <div class="uk-margin">
+ <button class="uk-button uk-button-primary" type="submit" name="submitFormSearch">
+ Search
+ </button>
+ </div>
+</form>
+
+<?php if(!empty($TemplateData['releases'])) { ?>
+<form class="uk-form-horizontal uk-margin-small" method="post" enctype="multipart/form-data">
+ <div class="uk-margin">
+ <div class="uk-form-controls">
+
+ <?php foreach($TemplateData['releases'] as $k=>$v) { ?>
+
+ <label><input class="uk-radio" type="radio" name="fdata[rselect]" value="<?php echo $k; ?>"> <?php echo $v; ?></label><br>
+
+ <?php } ?>
+ </div>
+ </div>
+
+ <div class="uk-margin">
+ <button class="uk-button uk-button-primary" type="submit" name="submitFormReleaseSelect">
+ Select
+ </button>
+ </div>
+</form>
+<?php } ?>
+
+<?php if(!empty($TemplateData['release'])) { ?>
+<a href="https://musicbrainz.org/release/<?php echo $TemplateData['release']['id']; ?>" target=_blank>Musibrainz release page</a>
+<form class="uk-form-horizontal uk-margin-small" method="post" enctype="multipart/form-data" uk-grid>
+
+ <?php foreach($TemplateData['release'] 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-2021 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
+ *
+ * https://musicbrainz.org/doc/Development
+ * http://musicbrainz.org/ws/2/release/?query=artist:broilers%20AND%20release:muerte%20AND%20format:CD&fmt=json
+ * http://musicbrainz.org/ws/2/release/5eb27466-fe5e-4683-aa9c-1ca396741c7c?&fmt=json
+ */
+
+require_once 'lib/musicbrainz.class.php';
+if(file_exists(PATH_ABSOLUTE.'/config/config-musicbrainz.php')) {
+ require_once 'config/config-musicbrainz.php';
+}
+
+$Brainz = new Musicbrainz(array(
+ 'resultLimit' => TOOL_BRAINZ_RESULT_LIMIT,
+ 'browserAgent' => TOOL_BRAINZ_BROWSER_AGENT,
+ 'browserLang' => TOOL_BRAINZ_BROWSER_ACCEPT_LANG,
+ 'browserAccept' => TOOL_BRAINZ_BROWSER_ACCEPT,
+ 'debug' => true
+));
+
+$TemplateData['releases'] = array();
+$TemplateData['release'] = array();
+$TemplateData['saveToSelection'] = '';
+
+// 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)) {
+ $artist = trim($fdata['artist']);
+ $artist = Summoner::validate($artist) ? $artist : false;
+ $album = trim($fdata['album']);
+ $album = Summoner::validate($album) ? $album : false;
+
+ if(!empty($artist) && !empty($album)) {
+ $releaseSearch = $Brainz->searchForRelease($artist, $album);
+
+ if(!empty($releaseSearch)) {
+ $TemplateData['releases'] = $releaseSearch;
+ } else {
+ $TemplateData['message']['content'] = "Nothing found.";
+ $TemplateData['message']['status'] = "error";
+ }
+ }
+ else {
+ $TemplateData['message']['content'] = "Invalid search term";
+ $TemplateData['message']['status'] = "error";
+ }
+ }
+}
+
+if(isset($_POST['submitFormReleaseSelect'])) {
+ if (isset($_POST['fdata'])) {
+ $fdata = $_POST['fdata'];
+ if (!empty($fdata)) {
+ $releaseId = $fdata['rselect'];
+ if(!empty($releaseId)) {
+ $releaseInfo = $Brainz->getReleaseInfo($releaseId);
+ if(!empty($releaseInfo)) {
+ $TemplateData['release'] = $releaseInfo;
+ } else {
+ $TemplateData['message']['content'] = "Nothing found.";
+ $TemplateData['message']['status'] = "error";
+ }
+ }
+ }
+ }
+ else {
+ $TemplateData['message']['content'] = "Invalid selection";
+ $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 == "image") {
+
+ $fieldData = array();
+
+ $_f = $Brainz->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";
+ }
+ }
+}
+
+/**
+ * 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_BRAINZ_FIELDS_TO is defined and a matching key=>value pair is available
+ *
+ * @param string $optionString
+ * @param string $key
+ * @return string
+ */
+function toolMethod_GetTargetSelection(string $optionString, string $key): string {
+ if(defined('TOOL_BRAINZ_FIELDS_TO') & !empty($key)) {
+ if(isset(TOOL_BRAINZ_FIELDS_TO[$key])) {
+ $_k = "sel_".TOOL_BRAINZ_FIELDS_TO[$key];
+ $optionString = str_replace($_k,'selected="selected"',$optionString);
+ }
+ }
+
+ return $optionString;
+}