loadDetails(); } } public function loadDetails() { if ($this->loaded) { return; } $this->editor = ''; $this->summary = ''; $this->media = ''; $this->isbn = ''; $this->collection = ''; $this->category = ''; $this->cover = ''; $sql_string = ''; // Introducing the cast as varchar(8000) to avoid the unixODBC LongText bug.. $sql_string .= "SELECT Tag, SubfieldCode, ContentShortPart, cast(ContentLongPart as varchar(3000)) as ContentLongPart, DisplayText "; $sql_string .= "FROM NoticeFields "; $sql_string .= "LEFT JOIN Authorities ON Authorities.AuthorityID = NoticeFields.AuthorityID "; $sql_string .= "WHERE NoticeID = " . $this->id . " "; $sql_string .= "ORDER BY Tag ASC, TagRepetition ASC, SubfieldCodeNr ASC;"; //print $sql_string; // ajout de l'url de l'image amazon $result = Connection::execute($sql_string, true); while ($row = $result->next()) { switch ($row['Tag']) { case '520': $this->summary = $this->addDetailToField(convertMSChar($this->summary), $row); break; case '260': $this->editor = $this->addDetailToField($this->editor, $row); break; case '300': $this->media = $this->addDetailToField($this->media, $row); break; case '020': $this->isbn = $this->addDetailToField($this->isbn, $row); break; case '490': $this->collection = $this->addDetailToField($this->collection, $row); break; case '600': case '610': case '650': case '651': case '655': case '690': case '691': case '695': case '696': $this->category = $this->addDetailToField($this->category, $row); break; case '901': $this->readBy = $this->addDetailToField($this->readBy, $row); break; case '856': if ($row['SubfieldCode'] == 'u') { $this->link = $this->addDetailToField($this->link, $row); } else if ($row['SubfieldCode'] == 'z') { $this->linkTitle = $this->addDetailToField($this->linkTitle, $row); } break; case '899': if ($row['SubfieldCode'] == 'a') { $this->cover = "http://ecx.images-amazon.com/images/I/" . $row['ContentShortPart'] . "._SL320_.jpg"; } } if ($this->coverdisplay == 2) { $this->cover = "http://fichiers.bibliothequesonore.ch:8089/netbiblio/images/covers/" . "Cover" . $this->id . "_Original.jpg"; } } $this->loaded = true; } private function addDetailToField($actualValue, $row) { $actualValue = ($actualValue ? $actualValue . ' ' : ''); $actualValue .= $row['ContentShortPart'] . $row['ContentLongPart'] . $row['DisplayText']; return $actualValue; } /** * 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 int|array $id * @return AudioBook|AudioBook[] */ public static function find($id) { $id = str_replace("'", "''", $id); $fullIdColumn = 'ab.'.AudioBook::$idColumn; if (is_array($id)) { if (count($id) > 0) { $condition = $fullIdColumn . ' IN (' . implode(', ', $id) . ')'; } else { $condition = "$fullIdColumn IS NULL"; // bad way of returning an empty ResultSet } $top = 'DISTINCT '; } else { $condition = "$fullIdColumn = $id"; $top = 'TOP 1'; } $sql = sprintf("SELECT %s ab.[%s] AS id, [Title] AS title, [Author] AS author, LTRIM(RTRIM(NoticeNr)) AS code, RTRIM(userdefined3code) AS code3, [code3Code].TextFre AS code3Long, [genreCode].TextFre AS genre, [genreCode].Code AS genreCode, [coverdisplay], [MediaType1Code] AS typeMedia1, 12 AS score, CONVERT(varchar, CreationDate, 102) AS date FROM [%s] AS ab INNER JOIN Codes code3Code ON ab.userdefined3code = code3Code.Code AND code3Code.Type=6 INNER JOIN Codes genreCode ON MediaType2Code = genreCode.Code AND genreCode.Type = 2 WHERE %s AND LTRIM(RTRIM(noticenr)) NOT LIKE '%%~%%' ORDER BY Author, Title ;", $top, self::$idColumn, self::$tableName, $condition); $result_set = Connection::execute($sql, true); if (is_array($id)) { $result = array(); foreach ($id as $book_id) { while ($row = $result_set->next()) { if ($row['id'] == $book_id) { $result[] = new AudioBook($row, TRUE); break; } } $result_set->rewind(); } } else { $row = $result_set->next(); if (!$row) { return null; // throw new Exception("NotFoundException"); } $result = new AudioBook($row, TRUE); } return $result; } /** * Return a book or an array of book given their notice number without any letter. * * if $code is an array, return an array of book. If not, return the first match. * * Due to the fact that notice number is incosistent in the Notices table, * we use the si_sentences view instead. * * @param string $code * @return AudioBook * @throws Exception * @throws SqlException */ public static function findByCode3($code) { $fullIdColumn = AudioBook::$tableName . '.' . AudioBook::$idColumn; if (is_array($code)) { $value = str_replace("'", "''", implode(" ", $code)); $value = str_replace(' ', "', '", $value); $top = ''; $condition = "si_sentences.[Key] IN ('" . $value . "')"; } else { $value = str_replace("'", "''", $code); $top = 'top 1'; $condition = "si_sentences.[Key] = '$value'"; } $sql_string = ''; $sql_string .= "SELECT $top $fullIdColumn as id, "; $sql_string .= "Title as title, Author as author, si_sentences.[Key] as code, "; $sql_string .= "Codes.TextFre As type, "; $sql_string .= "0 AS score "; $sql_string .= "FROM " . AudioBook::$tableName; $sql_string .= " INNER JOIN Codes ON " . AudioBook::$tableName . ".MediaType2Code = Codes.Code AND Codes.Type = 2 "; $sql_string .= " INNER JOIN si_sentences ON si_sentences.NoticeID = Notices.NoticeID"; $sql_string .= " AND si_sentences.Category = 'Code'"; $sql_string .= " WHERE ($condition) ORDER BY author, title;"; $result_set = Connection::execute($sql_string, false); if (is_array($code)) { $result = array(); foreach ($code as $book_code) { while ($row = $result_set->next()) { if ($row['code'] == $book_code) { $result[] = new AudioBook($row, FALSE); break; } } $result_set->rewind(); } } else { $row = $result_set->next(); if (!$row) { throw new Exception("NotFoundException"); } $result = new AudioBook($row, TRUE); } return $result; } public static function findByCode($code) { $fullIdColumn = AudioBook::$tableName . '.' . AudioBook::$idColumn; if (is_array($code)) { $value = str_replace("'", "''", implode(" ", $code)); $value = str_replace(' ', "', '", $value); $top = ''; $condition = "LTRIM(RTRIM(NoticeNr)) in ('" . $value . "')"; } else { $value = str_replace("'", "''", $code); $top = 'top 1'; $condition = "LTRIM(RTRIM(NoticeNr)) = '$value'"; } $sql_string = ''; $sql_string .= "SELECT $top $fullIdColumn as id, "; $sql_string .= "Notices.Title as title, Notices.Author as author, LTRIM(RTRIM(NoticeNr)) as code, "; $sql_string .= "Codes.TextFre As type, "; $sql_string .= "0 AS score "; $sql_string .= "FROM " . AudioBook::$tableName; $sql_string .= " INNER JOIN Codes ON " . AudioBook::$tableName . ".MediaType2Code = Codes.Code AND Codes.Type = 2 "; $sql_string .= " WHERE ($condition) ORDER BY author, title ;"; $result_set = Connection::execute($sql_string, false); if (is_array($code)) { $result = array(); while ($row = $result_set->next()) { $result[] = new AudioBook($row, true); } return $result; } else { $row = $result_set->next(); if (!$row) { throw new Exception("NotFoundException"); } $result[] = new AudioBook($row, true); } return $result; } /** * @param $code * @return int * @throws Exception * @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 Exception("NotFoundException"); } $row = $result->current(); return $row['NoticeId']; } /** * Retrieve the last books for each type. If 'type' is an empty string, then * it returns all types. */ public static function lastBooksByType($type, $itemsByGroup = 10) { $type_before_escape = $type; $type = Connection::escape(utf8_decode($type)); if ($type_before_escape == "Jeunesse") { if ($itemsByGroup < 20) $itemsByGroup = 20; $sqlQuery = " SELECT top " . $itemsByGroup . " Notices.NoticeId AS id, "; $sqlQuery .= " Notices.title AS title, "; $sqlQuery .= " Notices.author AS author, "; $sqlQuery .= " LTRIM(RTRIM(Notices.NoticeNr)) AS code, "; $sqlQuery .= " 'Jeunesse' AS type, 0 as score, "; $sqlQuery .= " convert(varchar, CreationDate, 102) as date "; $sqlQuery .= " FROM Notices "; $sqlQuery .= " WHERE Notices.NoticeNr NOT LIKE '%~%' "; $sqlQuery .= " AND Notices.NoticeNr NOT LIKE '%V%' "; $sqlQuery .= " AND Notices.NoticeNr NOT LIKE '%T%' "; $sqlQuery .= " AND Notices.MediaType1Code = 'CDD' "; $sqlQuery .= " AND Notices.Visible = 1 "; $sqlQuery .= " AND Notices.AgeCode in ('E', 'J') "; $sqlQuery .= " ORDER BY date DESC;"; } else { $sqlQuery = "WITH cte AS ( "; $sqlQuery .= " SELECT Notices.NoticeId AS id, "; $sqlQuery .= " Notices.title AS title, "; $sqlQuery .= " Notices.author AS author, "; $sqlQuery .= " LTRIM(RTRIM(Notices.NoticeNr)) AS code, "; $sqlQuery .= " Codes.TextFre AS type, "; $sqlQuery .= " convert(varchar, CreationDate, 102) as date, "; $sqlQuery .= " rank() OVER ( "; $sqlQuery .= " PARTITION BY Codes.TextFre "; $sqlQuery .= " ORDER BY cast(LTRIM(RTRIM(Notices.NoticeNr)) as int) DESC "; $sqlQuery .= " ) AS num "; $sqlQuery .= " FROM Notices "; $sqlQuery .= " INNER JOIN Codes "; $sqlQuery .= " ON Notices.MediaType2Code = Codes.Code "; $sqlQuery .= " WHERE Codes.Type = 2 "; if (strlen($type)) $sqlQuery .= " AND Codes.TextFre = " . $type . " "; $sqlQuery .= " AND Notices.NoticeNr NOT LIKE '%~%' "; $sqlQuery .= " AND Notices.NoticeNr NOT LIKE '%V%' "; $sqlQuery .= " AND Notices.NoticeNr NOT LIKE '%T%' "; $sqlQuery .= " AND Notices.MediaType1Code = 'CDD' "; $sqlQuery .= " AND Notices.Visible = 1 "; $sqlQuery .= " GROUP BY Codes.TextFre, "; $sqlQuery .= " Notices.NoticeNr, "; $sqlQuery .= " Notices.NoticeId, "; $sqlQuery .= " Notices.title, "; $sqlQuery .= " Notices.author, "; $sqlQuery .= " Notices.CreationDate "; $sqlQuery .= ") "; $sqlQuery .= "SELECT id, title, author, code, type, 0 as score, date "; $sqlQuery .= "FROM cte "; $sqlQuery .= "WHERE num <= " . intval($itemsByGroup) . " "; $sqlQuery .= "ORDER BY date DESC;"; } $resultSet = Connection::execute($sqlQuery); $result = array(); while (($row = $resultSet->next())) $result[] = new AudioBook($row, TRUE); return $result; } /** * 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); } }