You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
305 lines
12 KiB
PHP
305 lines
12 KiB
PHP
<?php
|
|
require_once('DbMapping.php');
|
|
|
|
class BookNotFoundException extends WebException {
|
|
public function __construct($code) {
|
|
parent::__construct('BookNotFound', "The book with code $code was not found", -404);
|
|
}
|
|
}
|
|
|
|
function convertMSChar($src)
|
|
{
|
|
$text = preg_replace('/([\xc0-\xdf].)/se', "'&#' . ((ord(substr('$1', 0, 1)) - 192) * 64 + (ord(substr('$1', 1, 1)) - 128)) . ';'", $src);
|
|
$text = preg_replace('/([\xe0-\xef]..)/se', "'&#' . ((ord(substr('$1', 0, 1)) - 224) * 4096 + (ord(substr('$1', 1, 1)) - 128) * 64 + (ord(substr('$1', 2, 1)) - 128)) . ';'", $text);
|
|
return $text;
|
|
}
|
|
|
|
/**
|
|
* AudioBook is mapped on a Notice from NetBiblio
|
|
*
|
|
* @property string id
|
|
* @property string sql_id
|
|
* @property string title
|
|
* @property string sql_title
|
|
* @property string author
|
|
* @property string sql_author
|
|
* @property string code
|
|
* @property string sql_code
|
|
* @property string summary
|
|
* @property string sql_summary
|
|
* @property string editor
|
|
* @property string sql_editor
|
|
* @property string media
|
|
* @property string sql_media
|
|
* @property string collection
|
|
* @property string sql_collection
|
|
* @property string isbn
|
|
* @property string sql_isbn
|
|
* @property string readBy
|
|
* @property string sql_readBy
|
|
* @property string cover
|
|
* @property string sql_cover
|
|
* @property string category
|
|
* @property string sql_category
|
|
* @property string date
|
|
* @property string sql_date
|
|
* @property string code3
|
|
* @property string sql_code3
|
|
* @property string code3Long
|
|
* @property string sql_code3Long
|
|
* @property string genre
|
|
* @property string sql_genre
|
|
* @property string genreCode
|
|
* @property string sql_genreCode
|
|
* @property string coverdisplay
|
|
* @property string sql_coverdisplay
|
|
* @property string link
|
|
* @property string sql_link
|
|
* @property string linkTitle
|
|
* @property string sql_linkTitle
|
|
* @property string typeMedia1
|
|
* @property string sql_typeMedia1
|
|
*/
|
|
class AudioBook extends DbMapping
|
|
{
|
|
protected $attributeNames = 'id title author code summary editor media collection isbn readBy cover category date code3 code3Long genre genreCode coverdisplay link linkTitle typeMedia1';
|
|
|
|
public static function find($id) {
|
|
return self::findBy('NoticeID', $id);
|
|
}
|
|
|
|
/**
|
|
* If $id is an array, return an array of book, if it is only one id, return one book
|
|
* Load books details only if not an array.
|
|
*
|
|
* Beware that this search use the NoticeID, not the NoticeNr, if you need the last one
|
|
* use findByCode method instead;
|
|
*
|
|
* @param string $column
|
|
* @param int|array $ids
|
|
* @param bool $raw results ?
|
|
* @return AudioBook|AudioBook[]|array
|
|
*/
|
|
public static function findBy($column, $ids, $raw = false)
|
|
{
|
|
$multiple = true;
|
|
if(! is_array($ids)) {
|
|
$ids = array($ids);
|
|
$multiple = false;
|
|
}
|
|
|
|
$sql = sprintf("SELECT DISTINCT
|
|
Notices.[NoticeID] AS id,
|
|
Notices.[Title] AS title,
|
|
Notices.[Author] AS author,
|
|
LTRIM(RTRIM(Notices.[NoticeNr])) AS code,
|
|
Fields.[520] AS summary,
|
|
Fields.[260b] + ' ' + Fields.[260c] AS editor,
|
|
Fields.[300] AS media,
|
|
Fields.[490a] AS collection,
|
|
isbn.DisplayText AS isbn,
|
|
Fields.[901] AS readBy,
|
|
Fields.[899a] AS cover,
|
|
'' AS category, -- supposed to come from tags 600, 610, 650, 651, 655, 690, 691, 695, 696 but always empty anyway
|
|
CONVERT(VARCHAR, Notices.[CreationDate], 102) AS date,
|
|
LTRIM(RTRIM(Notices.[userdefined3code])) AS code3,
|
|
[Code3].TextFre AS code3Long,
|
|
[GenreCode].TextFre AS genre,
|
|
[GenreCode].Code AS genreCode,
|
|
Notices.[coverdisplay],
|
|
Fields.[856u] AS link,
|
|
Fields.[856z] AS linkTitle,
|
|
Notices.[MediaType1Code] AS typeMedia1
|
|
FROM Notices
|
|
INNER JOIN Codes AS Code3 ON Notices.userdefined3code = Code3.Code AND Code3.Type=6
|
|
INNER JOIN Codes AS GenreCode ON MediaType2Code = GenreCode.Code AND GenreCode.Type = 2
|
|
LEFT OUTER JOIN (
|
|
SELECT *
|
|
FROM (
|
|
SELECT
|
|
NoticeID,
|
|
CASE
|
|
WHEN Tag IN ('490', '260', '856', '899') THEN Tag + SubfieldCode
|
|
ELSE Tag
|
|
END AS Field,
|
|
CASE
|
|
WHEN Tag = '020' THEN CAST(AuthorityID AS varchar)
|
|
ELSE ContentShortPart
|
|
END AS Data
|
|
FROM NoticeFields
|
|
WHERE
|
|
Tag IN (
|
|
'520', -- summary
|
|
'901', -- Reader
|
|
'300', -- Duration (field media)
|
|
'020' -- ISBN
|
|
)
|
|
OR (Tag = '490' AND SubfieldCode = 'a') -- Collection
|
|
OR (Tag = '260' AND SubfieldCode = 'b') -- Editor
|
|
OR (Tag = '260' AND SubfieldCode = 'c') -- Edition year
|
|
OR (Tag = '856' AND SubfieldCode = 'u') -- Link
|
|
OR (Tag = '856' AND SubfieldCode = 'z') -- Link title
|
|
OR (Tag = '899' AND SubfieldCode = 'a') -- Cover
|
|
) AS src
|
|
PIVOT (
|
|
MIN(Data)
|
|
FOR Field IN ([520], [901], [300], [020], [490a], [260b], [260c], [856u], [856z], [899a])
|
|
) AS pvt
|
|
) Fields ON Notices.NoticeID = Fields.NoticeID
|
|
LEFT JOIN Authorities AS isbn ON isbn.AuthorityID = Fields.[020]
|
|
WHERE
|
|
LTRIM(RTRIM(Notices.[%s])) IN ('%s')
|
|
AND Notices.[NoticeNr] NOT LIKE '%%~%%'
|
|
;", $column, implode('\', \'', $ids));
|
|
|
|
$result = Connection::execute($sql, true);
|
|
|
|
$books = array();
|
|
while($row = $result->next()) {
|
|
if($row['coverdisplay'] == 2) {
|
|
$row['cover'] = 'http://fichiers.bibliothequesonore.ch:8089/netbiblio/images/covers/Cover'.$row['id'].'_Original.jpg';
|
|
} else if(strlen($row['cover']) > 0) {
|
|
$row['cover'] = 'http://ecx.images-amazon.com/images/I/'.$row['cover'].'._SL320_.jpg';
|
|
}
|
|
|
|
$books[$row['id']] = $raw ? $row : new AudioBook($row);
|
|
}
|
|
|
|
return $multiple ? $books : reset($books);
|
|
}
|
|
|
|
/**
|
|
* @param $code
|
|
* @return int
|
|
* @throws BookNotFoundException
|
|
* @throws SqlException
|
|
*/
|
|
public static function findIdByCode($code)
|
|
{
|
|
$sql = "SELECT NoticeId FROM Notices WHERE LTRIM(RTRIM(NoticeNr)) = '$code';";
|
|
$result = Connection::execute($sql, false);
|
|
if ($result === false || $result->length == 0) {
|
|
throw new BookNotFoundException($code);
|
|
}
|
|
|
|
$row = $result->current();
|
|
return $row['NoticeId'];
|
|
}
|
|
|
|
/**
|
|
* Retrieve the list of all readers (volunteers) having read at least 4 books (2 notices per book).
|
|
* Returns an associative array containing $lastname and $firstname
|
|
*/
|
|
public static function listOfReaders()
|
|
{
|
|
$sql = "SELECT
|
|
count(*),
|
|
ContentShortPart AS name
|
|
FROM NoticeFields
|
|
WHERE Tag=901
|
|
GROUP BY ContentShortPart
|
|
HAVING count(*) > 6
|
|
ORDER BY SUBSTRING(ContentShortPart, CHARINDEX(' ', ContentShortPart)+1, 15);";
|
|
|
|
$results = Connection::execute($sql);
|
|
return array_map(function($row) {
|
|
$fullname = str_replace("*", "", $row['name']);
|
|
$parts = explode(" ", $fullname);
|
|
$firstname = array_shift($parts);
|
|
$lastname = implode(" ", $parts);
|
|
return array(
|
|
'lastname' => $lastname,
|
|
'firstname' => $firstname);
|
|
}, $results->to_array());
|
|
}
|
|
|
|
/**
|
|
* Retrieve the list of all categories
|
|
*/
|
|
public static function listOfCategories()
|
|
{
|
|
$sql = "SELECT
|
|
LTRIM(RTRIM(Code)) as code,
|
|
TextFre AS text
|
|
FROM Codes
|
|
WHERE
|
|
type=2
|
|
AND Code!='-'
|
|
ORDER BY TextFre;";
|
|
|
|
$results = Connection::execute($sql);
|
|
return array_map(function($row) {
|
|
return array(
|
|
'code' => $row['code'],
|
|
'text' => $row['text'],
|
|
);
|
|
}, $results->to_array());
|
|
}
|
|
|
|
/**
|
|
* Retrieve the list of all type available in the database.
|
|
*/
|
|
public static function listOfTypes()
|
|
{
|
|
$sql = "SELECT DISTINCT
|
|
Codes.TextFre AS type
|
|
FROM Codes
|
|
INNER JOIN Notices ON Codes.Code = Notices.MediaType2Code
|
|
WHERE
|
|
Codes.Type = 2
|
|
AND Notices.NoticeNr NOT LIKE '%~%'
|
|
AND Notices.NoticeNr NOT LIKE '%V%'
|
|
AND Notices.NoticeNr NOT LIKE '%T%'
|
|
AND Notices.MediaType1Code = 'CDD';";
|
|
|
|
$results = Connection::execute($sql);
|
|
$results = array_map(function($r) {
|
|
return $r['type'];
|
|
}, $results->to_array());
|
|
array_unshift($results, "Jeunesse");
|
|
|
|
return $results;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the list of all books currently lended to readers.
|
|
*/
|
|
public static function inReading()
|
|
{
|
|
$sql = "SELECT
|
|
noticenr, title, author, displayName
|
|
FROM notices, items, circulations, useraccounts
|
|
WHERE
|
|
mediatype1code='N' and NoticeNr not like '%~%'
|
|
AND items.noticeid = notices.noticeid
|
|
AND items.ItemID=circulations.ItemID
|
|
AND useraccounts.useraccountid=circulations.useraccountid
|
|
ORDER BY author, title;";
|
|
|
|
$results = Connection::execute($sql);
|
|
return array_map(function($row) {
|
|
return array(
|
|
"noticenr" => $row['noticenr'],
|
|
"auteur" => $row['author'],
|
|
"titre" => $row['title'],
|
|
"lecteur" => $row['displayName']
|
|
);
|
|
}, $results->to_array());
|
|
}
|
|
|
|
public function to_array()
|
|
{
|
|
if (!$this->loaded) {
|
|
$this->loadDetails();
|
|
}
|
|
return parent::to_array();
|
|
}
|
|
|
|
public function __set($name, $value)
|
|
{
|
|
if ($name == 'code' && is_string($value)) {
|
|
$value = preg_replace('/[~a-zA-Z]/', '', $value);
|
|
}
|
|
parent::__set($name, $value);
|
|
}
|
|
} |