mirror of
https://github.com/Yetangitu/owncloud-apps.git
synced 2025-10-02 14:49:17 +02:00
181 lines
4.7 KiB
PHP
181 lines
4.7 KiB
PHP
<?php
|
||
|
||
/**
|
||
* ownCloud - Files_Opds App
|
||
*
|
||
* @author Frank de Lange
|
||
* @copyright 2014 Frank de Lange
|
||
*
|
||
* This file is licensed under the Affero General Public License version 3 or
|
||
* later.
|
||
*/
|
||
|
||
namespace OCA\Files_Opds;
|
||
|
||
/**
|
||
* ISBN class for OPDS
|
||
*/
|
||
class Isbn
|
||
{
|
||
const SUCCESS = 0;
|
||
const REQUEST_LIMIT_EXCEEDED = -1;
|
||
const NOT_FOUND = -2;
|
||
const ERROR = -3;
|
||
const RESCAN_LIMIT_EXCEEDED = 86400;
|
||
const RESCAN_NOT_FOUND = 604800;
|
||
const RESCAN_ERROR = 86400;
|
||
|
||
/**
|
||
* @brief try to find a valid ISBN in the given text, using a cascade of
|
||
* regexps.
|
||
*
|
||
* @param string $text text to search through
|
||
* @return string $hit ISBN on success, false otherwise
|
||
*/
|
||
public static function scan($text) {
|
||
$match = array();
|
||
foreach($text as $line) {
|
||
/* generic ISBN 10/13 pattern. Checks for unicode dashes ('‒–—―‑‐﹣--') as well as regular hyphens. */
|
||
if(preg_match_all('/ISBN(?:[ ‒–—―‑‐﹣--]?(?:1[03])?)?:?\s*(?=[\d Xx‒–—―‑‐﹣--]{10,17})(((?:97[89])[\d ‒–—―‑‐﹣--]{9,14})|([\d ‒–—―‑‐﹣--]{9,12}[\dXx]))/u', $line, $match)) {
|
||
foreach($match[1] as $hit) {
|
||
$hit = preg_replace('/[^0-9X]/i','',$hit);
|
||
if(self::validate($hit)) {
|
||
return $hit;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* If nothing found, try prefix-less versions. Even though ISBN numbers should be
|
||
* presented with a 'ISBN' prefix, some publications omit this. These patterns
|
||
* are liable to generate false positives, so they should only be run after the
|
||
* prefixed version has exhausted the search without returning results.
|
||
*/
|
||
|
||
foreach($text as $line) {
|
||
/* prefix-less ISBN-13 targeted pattern */
|
||
if(preg_match_all('/(97[89][\d ‒–—―‑‐﹣--]\d{9,13}\d)/u',$line,$match)) {
|
||
foreach($match[1] as $hit) {
|
||
$hit = preg_replace('/[^0-9]/','',$hit);
|
||
if(self::validate($hit)) {
|
||
return $hit;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* single ISBN-10 targeted pattern */
|
||
if(preg_match_all('/(\d[\d ‒–—―‑‐﹣--]{8,11}[\dXx])/u',$line,$match)) {
|
||
foreach($match[1] as $hit) {
|
||
$hit = preg_replace('/[^0-9X]/i','',$hit);
|
||
if(self::validate($hit)) {
|
||
return $hit;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* No ISBN found */
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* @brief get metadata for given ISBN
|
||
*
|
||
* @param string $isbn ISBN to use
|
||
* @param arrayref &$meta OPDS metadata
|
||
* @return bool $success (true if metadata found)
|
||
*/
|
||
public static function get($isbn,&$meta) {
|
||
/* set ISBN in metadata; can be overwritten later with ISBN13 */
|
||
$meta['isbn'] = $isbn;
|
||
/* try Google first, then ISBNdb */
|
||
if (!(Isbn::SUCCESS == Google::get($isbn,$meta)) && (!(Isbn::SUCCESS == Isbndb::get($isbn,$meta)) )) {
|
||
/* Try ISBNdb, then Google */
|
||
//if (!(Isbn::SUCCESS == Isbndb::get($isbn,$meta)) && (!(Isbn::SUCCESS == Google::get($isbn,$meta)))) {
|
||
return false;
|
||
} else {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief validate ISBN
|
||
*
|
||
* @param string $isbn ISBN to validate
|
||
* @return bool true if ISBN is valid
|
||
*/
|
||
public static function validate($isbn) {
|
||
if (null === $isbn || '' === $isbn) {
|
||
return false;
|
||
}
|
||
|
||
switch (strlen($isbn)) {
|
||
case 10:
|
||
return self::isIsbn10($isbn);
|
||
break;
|
||
case 13:
|
||
return self::isIsbn13($isbn);
|
||
break;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* @brief check for valid ISBN10
|
||
* @param string $isbn ISBN to check
|
||
* @return bool true if valid ISBN-10
|
||
*/
|
||
static function isIsbn10 ($isbn) {
|
||
$len = strlen($isbn);
|
||
if ($len == 10) {
|
||
//Calculate check digit
|
||
$check = 0;
|
||
for ($i = 0; $i < 9; $i++) {
|
||
if ($isbn[$i] === "X") {
|
||
$check += 10 * intval(10 - $i);
|
||
} else {
|
||
$check += intval($isbn[$i]) * intval(10 - $i);
|
||
}
|
||
}
|
||
$check = 11 - $check % 11;
|
||
if ($check === 10) {
|
||
$check = 'X';
|
||
} elseif ($check === 11) {
|
||
$check = 0;
|
||
}
|
||
|
||
return ($check == $isbn{$len - 1});
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* @brief check for valid ISBN13
|
||
* @param string $isbn ISBN to check
|
||
* @return bool true if valid ISBN-13
|
||
*/
|
||
static function isIsbn13 ($isbn) {
|
||
$len = strlen($isbn);
|
||
if ($len == 13) {
|
||
//Calculate check digit
|
||
$check = 0;
|
||
for ($i = 0; $i < 12; $i += 2) {
|
||
$check += substr($isbn, $i, 1);
|
||
}
|
||
for ($i = 1; $i < 12; $i += 2) {
|
||
$check += 3 * substr($isbn, $i, 1);
|
||
}
|
||
$check = 10 - $check % 10;
|
||
if ($check === 10) {
|
||
$check = 0;
|
||
}
|
||
|
||
return ($check == $isbn{$len - 1});
|
||
}
|
||
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|