first blood
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.idea
|
||||||
|
*configuration.local.php
|
||||||
98
configuration.php
Normal file
98
configuration.php
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Configuration {
|
||||||
|
private static $instance = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ! WARNING !
|
||||||
|
*
|
||||||
|
* Those are default values, if you need to change them for a particular host,
|
||||||
|
* please just create a file named 'configuration.local.php' in the same directory
|
||||||
|
* and redefine the values there !
|
||||||
|
*
|
||||||
|
* This file must contain an array named $configuration containing the keys you
|
||||||
|
* want to redefine. Then, those values will be used to replace those in the
|
||||||
|
* array defined just below.
|
||||||
|
*
|
||||||
|
* @var array configuration values
|
||||||
|
*/
|
||||||
|
private $values = array(
|
||||||
|
'db' => array(
|
||||||
|
'driver' => 'SQL Server Native Client 11.0',
|
||||||
|
'server' => 'BSR2012\SQLEXPRESS,1433',
|
||||||
|
'username' => 'alcoda',
|
||||||
|
'password' => 'alcodaonly',
|
||||||
|
'name' => 'NetBiblio3',
|
||||||
|
),
|
||||||
|
'solr' => array(
|
||||||
|
'server' => '192.168.1.250',
|
||||||
|
'port' => '8983',
|
||||||
|
'username' => '',
|
||||||
|
'password' => '',
|
||||||
|
'result_count' => 10,
|
||||||
|
),
|
||||||
|
'log' => array(
|
||||||
|
'file' => 'c:\\logs\\ws_ipad.txt',
|
||||||
|
'active' => false,
|
||||||
|
),
|
||||||
|
'session' => array(
|
||||||
|
'save_path' => ''
|
||||||
|
),
|
||||||
|
|
||||||
|
'checkfile_url' => 'http://fichiers.bibliothequesonore.ch/checkfile.php?',
|
||||||
|
|
||||||
|
'netbiblio_worker_id' => 45,
|
||||||
|
'www_employee_id' => 45,
|
||||||
|
'www_library_id' => 2,
|
||||||
|
);
|
||||||
|
|
||||||
|
private $custom_config = 'configuration.local.php';
|
||||||
|
|
||||||
|
private function __construct() {
|
||||||
|
// by default, set the session save path to the default value;
|
||||||
|
$this->values['session']['save_path'] = session_save_path();
|
||||||
|
|
||||||
|
if(file_exists($this->custom_config)) {
|
||||||
|
require_once($this->custom_config);
|
||||||
|
|
||||||
|
if(! isset($configuration) || ! is_array($configuration)) {
|
||||||
|
throw new RuntimeException("You custom configuration in '{$this->custom_config}' must be in a variable named '\$configuration' and be an array.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->values = array_replace_recursive($this->values, $configuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function dotNotationAccess($data, $key, $default=null)
|
||||||
|
{
|
||||||
|
$keys = explode('.', $key);
|
||||||
|
foreach ($keys as $k) {
|
||||||
|
if (!is_array($data)) {
|
||||||
|
throw new Exception("Try to access non-array as array, key '$key''");
|
||||||
|
}
|
||||||
|
if (!isset($data[$k])) {
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $data[$k];
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function value($name, $default) {
|
||||||
|
return $this->dotNotationAccess($this->values, $name, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $name
|
||||||
|
* @param mixed $default the default value for your configuration option
|
||||||
|
* @return mixed return the configuration value if the key is find, the default otherwise
|
||||||
|
*/
|
||||||
|
public static function get($name, $default = null) {
|
||||||
|
if(is_null(self::$instance)) {
|
||||||
|
self::$instance = new Configuration();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instance->value($name, $default);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
global.php
Normal file
4
global.php
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once('configuration.php');
|
||||||
|
require_once('lib/Connection.php');
|
||||||
574
lib/AudioBook.php
Normal file
574
lib/AudioBook.php
Normal file
@@ -0,0 +1,574 @@
|
|||||||
|
<?php
|
||||||
|
require_once('DbMapping.php');
|
||||||
|
|
||||||
|
|
||||||
|
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 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 typeMedia1
|
||||||
|
* @property string sql_typeMedia1
|
||||||
|
*
|
||||||
|
* @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 score
|
||||||
|
* @property string sql_score
|
||||||
|
* @property string type
|
||||||
|
* @property string sql_type
|
||||||
|
* @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 itemNr
|
||||||
|
* @property string sql_itemNr
|
||||||
|
*/
|
||||||
|
class AudioBook extends DbMapping
|
||||||
|
{
|
||||||
|
public static $tableName = 'Notices';
|
||||||
|
public static $idColumn = 'NoticeID';
|
||||||
|
|
||||||
|
protected $extendedAttributeNames = 'summary editor media collection isbn readBy cover typeMedia1';
|
||||||
|
protected $attributeNames = 'id title author code score summary editor media collection isbn readBy cover type category date code3 code3Long genre genreCode coverdisplay link linkTitle itemNr typeMedia1';
|
||||||
|
|
||||||
|
private $loaded = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an AudioBook
|
||||||
|
* @param array $attributes
|
||||||
|
* @param bool $doLoadDetails
|
||||||
|
*/
|
||||||
|
public function __construct($attributes, $doLoadDetails = FALSE)
|
||||||
|
{
|
||||||
|
parent::__construct($attributes);
|
||||||
|
if ($doLoadDetails) {
|
||||||
|
$this->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.bsr-lausanne.ch:8089/Netbiblio3/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);
|
||||||
|
}
|
||||||
|
}
|
||||||
78
lib/BookSearch.php
Normal file
78
lib/BookSearch.php
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
mb_http_output('UTF-8');
|
||||||
|
|
||||||
|
class BookSearch
|
||||||
|
{
|
||||||
|
/** @var SolrClient */
|
||||||
|
private $client;
|
||||||
|
/** @var SolrQuery */
|
||||||
|
private $query;
|
||||||
|
private $queryParts = array();
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$options = array
|
||||||
|
(
|
||||||
|
'hostname' => Configuration::get('solr.server'),
|
||||||
|
'port' => Configuration::get('solr.port'),
|
||||||
|
'login' => Configuration::get('solr.username'),
|
||||||
|
'password' => Configuration::get('solr.password'),
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->client = new SolrClient($options);
|
||||||
|
$this->query = new SolrQuery();
|
||||||
|
$this->query->setQuery('*:*');
|
||||||
|
$this->query->addField('id');
|
||||||
|
$this->query->addField('code');
|
||||||
|
$this->query->addParam('q.op', 'AND');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addQuery($queryText, $queryField = '')
|
||||||
|
{
|
||||||
|
if ($queryField != '')
|
||||||
|
$queryText = "$queryField:($queryText)";
|
||||||
|
|
||||||
|
$this->queryParts[] = $queryText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addResultField($field)
|
||||||
|
{
|
||||||
|
$this->query->addField($field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addSortField($field, $order = SolrQuery::ORDER_DESC)
|
||||||
|
{
|
||||||
|
$this->query->addSortField($field, $order);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addFacet($field, $minCount = 2)
|
||||||
|
{
|
||||||
|
$this->query->setFacet(true);
|
||||||
|
$this->query->addFacetField($field);
|
||||||
|
$this->query->setFacetMinCount($minCount, $field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setYearInterval($beginning = 0, $end = 2500)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $start
|
||||||
|
* @param int $count
|
||||||
|
* @return SolrObject
|
||||||
|
*/
|
||||||
|
public function getResults($start = 0, $count = 15)
|
||||||
|
{
|
||||||
|
if (count($this->queryParts) == 0)
|
||||||
|
$query = '*:*';
|
||||||
|
else {
|
||||||
|
$query = implode(' AND ', $this->queryParts);
|
||||||
|
}
|
||||||
|
$this->query->setQuery($query);
|
||||||
|
$this->query->setStart($start);
|
||||||
|
$this->query->setRows($count);
|
||||||
|
|
||||||
|
return $this->client->query($this->query)->getResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
205
lib/Connection.php
Normal file
205
lib/Connection.php
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Connection
|
||||||
|
{
|
||||||
|
// Internal variable to hold the connection
|
||||||
|
private static $db;
|
||||||
|
|
||||||
|
final private function __construct() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $query
|
||||||
|
* @param bool $throw_error
|
||||||
|
* @return OdbcResultSet|resource|string
|
||||||
|
* @throws SqlException
|
||||||
|
*/
|
||||||
|
public static function execute($query, $throw_error = false)
|
||||||
|
{
|
||||||
|
$result = odbc_exec(self::get(), utf8_decode($query));
|
||||||
|
$result = new OdbcResultSet($result);
|
||||||
|
|
||||||
|
if ($result->is_error()) {
|
||||||
|
if($throw_error) {
|
||||||
|
throw new SqlException($result->get_error(), $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result->get_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function get()
|
||||||
|
{
|
||||||
|
if (is_null(self::$db)) {
|
||||||
|
$dsn = sprintf(
|
||||||
|
"Driver={%s};Server=%s;Database=%s;",
|
||||||
|
Configuration::get('db.driver'),
|
||||||
|
Configuration::get('db.server'),
|
||||||
|
Configuration::get('db.name')
|
||||||
|
);
|
||||||
|
self::$db = odbc_pconnect($dsn, Configuration::get('db.username'), Configuration::get('db.password'));
|
||||||
|
|
||||||
|
if (self::$db === false) {
|
||||||
|
throw new SqlException("Unable to connect to the server.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Return the connection
|
||||||
|
return self::$db;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function escape($data)
|
||||||
|
{
|
||||||
|
if (is_numeric($data))
|
||||||
|
return $data;
|
||||||
|
$unpacked = unpack('H*hex', $data);
|
||||||
|
return '0x' . $unpacked['hex'];
|
||||||
|
}
|
||||||
|
|
||||||
|
final private function __clone() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SqlException extends Exception
|
||||||
|
{
|
||||||
|
private $query;
|
||||||
|
|
||||||
|
public function __construct($message = "Sql Error", $query = "")
|
||||||
|
{
|
||||||
|
$this->query = $query;
|
||||||
|
parent::__construct($message, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSqlError()
|
||||||
|
{
|
||||||
|
return $this->getMessage().' while executing: '.$this->query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OdbcResultSet implements Iterator, ArrayAccess
|
||||||
|
{
|
||||||
|
public $length;
|
||||||
|
|
||||||
|
private $results;
|
||||||
|
private $error;
|
||||||
|
private $num_fields;
|
||||||
|
private $cursor_index;
|
||||||
|
|
||||||
|
public function __construct($odbc_result)
|
||||||
|
{
|
||||||
|
if ($odbc_result === false) {
|
||||||
|
$this->error = odbc_errormsg(Connection::get());
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
$this->results = array();
|
||||||
|
$this->num_fields = odbc_num_fields($odbc_result);
|
||||||
|
|
||||||
|
if ($this->num_fields > 0) {
|
||||||
|
while ($row = odbc_fetch_row($odbc_result)) {
|
||||||
|
$data = array();
|
||||||
|
for ($i = 1; $i <= $this->num_fields; ++$i) {
|
||||||
|
$data[odbc_field_name($odbc_result, $i)] = utf8_encode(odbc_result($odbc_result, $i));
|
||||||
|
}
|
||||||
|
$this->results[] = $data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (Exception $e) {
|
||||||
|
print($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->cursor_index = 0;
|
||||||
|
$this->length = count($this->results);
|
||||||
|
odbc_free_result($odbc_result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function is_error()
|
||||||
|
{
|
||||||
|
return ($this->error ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_error()
|
||||||
|
{
|
||||||
|
return $this->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_row()
|
||||||
|
{
|
||||||
|
return $this->current();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function to_array()
|
||||||
|
{
|
||||||
|
return $this->results;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArrayAccess
|
||||||
|
/**
|
||||||
|
* @param int $offset
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function offsetExists($offset)
|
||||||
|
{
|
||||||
|
return !$this->error && $this->cursor_index < $this->length && $this->cursor_index >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $offset
|
||||||
|
* @return bool|array
|
||||||
|
*/
|
||||||
|
public function offsetGet($offset)
|
||||||
|
{
|
||||||
|
return $this->offsetExists($offset) ? $this->results[$offset] : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetSet($offset, $value)
|
||||||
|
{
|
||||||
|
if($this->offsetExists($offset)) {
|
||||||
|
$this->results[$offset] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetUnset($offset)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("This makes no sense at all.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterator
|
||||||
|
/**
|
||||||
|
* @return bool|array
|
||||||
|
*/
|
||||||
|
public function current()
|
||||||
|
{
|
||||||
|
return $this->offsetGet($this->cursor_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function key()
|
||||||
|
{
|
||||||
|
return $this->cursor_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|bool
|
||||||
|
*/
|
||||||
|
public function next()
|
||||||
|
{
|
||||||
|
$current = $this->current();
|
||||||
|
++$this->cursor_index;
|
||||||
|
return $current;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rewind()
|
||||||
|
{
|
||||||
|
$this->cursor_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function valid()
|
||||||
|
{
|
||||||
|
return $this->offsetExists($this->cursor_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
136
lib/DbMapping.php
Normal file
136
lib/DbMapping.php
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for mapping objects. inherit you database filled objects from here.
|
||||||
|
*
|
||||||
|
* @property int $id
|
||||||
|
*/
|
||||||
|
abstract class DbMapping
|
||||||
|
{
|
||||||
|
protected $attributes;
|
||||||
|
protected $attributeNames = '';
|
||||||
|
protected $privateAttributeNames = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $attributes
|
||||||
|
*/
|
||||||
|
public function __construct(array $attributes)
|
||||||
|
{
|
||||||
|
$this->setAttributes($attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define a bunch of attribute given by an associative array
|
||||||
|
* @param array $attributes
|
||||||
|
*/
|
||||||
|
public function setAttributes(array $attributes)
|
||||||
|
{
|
||||||
|
$this->assertAttributes($attributes);
|
||||||
|
foreach ($attributes as $key => $value) {
|
||||||
|
$this->__set($key, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that all keys from attributes are authorized
|
||||||
|
* @param array $attributes
|
||||||
|
*/
|
||||||
|
private function assertAttributes(array $attributes)
|
||||||
|
{
|
||||||
|
foreach ($attributes as $key => $value) {
|
||||||
|
$this->assertAttribute($key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that name attribute is authorized
|
||||||
|
* If public_only is false, check agains PRIVATE_ATTRIBUTES_NAME too.
|
||||||
|
* Those one cannot be accessed via setAttributes and other batch methods.
|
||||||
|
* @param string $name
|
||||||
|
* @param bool $public_only
|
||||||
|
* @throws InvalidAttributeException if the attribute is not a valid one
|
||||||
|
*/
|
||||||
|
private function assertAttribute($name, $public_only = TRUE)
|
||||||
|
{
|
||||||
|
if (strpos($this->attributeNames, $name) === false && ($public_only || strpos($this->privateAttributeNames, $name) === false)) {
|
||||||
|
throw(new InvalidAttributeException("The attribute $name is invalid"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a user attribute or the linked whishes
|
||||||
|
*
|
||||||
|
* If the name start with sql_, escape the string before to return it to avoid SQL injection.
|
||||||
|
* @param string $name
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __get($name)
|
||||||
|
{
|
||||||
|
$sql_safe = FALSE;
|
||||||
|
if (strpos($name, 'sql_') === 0) {
|
||||||
|
$name = substr($name, 4);
|
||||||
|
$sql_safe = TRUE;
|
||||||
|
}
|
||||||
|
$this->assertAttribute($name, false);
|
||||||
|
if (isset($this->attributes[$name])) {
|
||||||
|
$value = $this->attributes[$name];
|
||||||
|
if ($sql_safe) {
|
||||||
|
$value = str_replace("'", "''", $value);
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function to_array() {
|
||||||
|
return $this->attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a user attribute
|
||||||
|
* @param string $name
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public function __set($name, $value)
|
||||||
|
{
|
||||||
|
$this->assertAttribute($name, false);
|
||||||
|
$this->attributes[$name] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reload()
|
||||||
|
{
|
||||||
|
$this->setAttributes(DbMapping::find($this->id)->toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to retrieve data from an id.
|
||||||
|
* @param int $id
|
||||||
|
* @return DbMapping
|
||||||
|
*/
|
||||||
|
abstract public static function find($id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all the public attributes in an array;
|
||||||
|
*/
|
||||||
|
public function toArray()
|
||||||
|
{
|
||||||
|
$result = array();
|
||||||
|
foreach ($this->attributes as $name => $value) {
|
||||||
|
if (strpos($this->attributeNames, $name) !== false) {
|
||||||
|
$result[$name] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception raised when an invalid attribute name is accessed
|
||||||
|
*/
|
||||||
|
class InvalidAttributeException extends Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
282
lib/User.php
Normal file
282
lib/User.php
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
<?php
|
||||||
|
require_once('DbMapping.php');
|
||||||
|
require_once('AudioBook.php');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User is mapped on the Useraccounts table. Contains user information : id, login, firstName, lastName, displayName.
|
||||||
|
*
|
||||||
|
* @property int id
|
||||||
|
* @property string $login
|
||||||
|
* @property string $sql_login
|
||||||
|
* @property string $password
|
||||||
|
* @property string $sql_password
|
||||||
|
* @property string $privatePhone
|
||||||
|
* @property string $sql_privatePhone
|
||||||
|
* @property string $officePhone
|
||||||
|
* @property string $sql_officePhone
|
||||||
|
* @property string $mobilePhone
|
||||||
|
* @property string $sql_mobilePhone
|
||||||
|
* @property string $addressId
|
||||||
|
* @property string $sql_addressId
|
||||||
|
* @property string $displayName
|
||||||
|
* @property string $sql_displayName
|
||||||
|
* @property string $firstName
|
||||||
|
* @property string $sql_firstName
|
||||||
|
* @property string $lastName
|
||||||
|
* @property string $sql_lastName
|
||||||
|
* @property string $mail
|
||||||
|
* @property string $sql_mail
|
||||||
|
*/
|
||||||
|
class User extends DbMapping
|
||||||
|
{
|
||||||
|
public static $tableName = 'Useraccounts';
|
||||||
|
public static $idColumn = 'UseraccountID';
|
||||||
|
|
||||||
|
protected static $addressTableName = 'Addresses';
|
||||||
|
protected static $addressIdColumn = 'AddressID';
|
||||||
|
protected static $wishTableName = 'Wishes';
|
||||||
|
protected static $circulationTableName = 'Circulations';
|
||||||
|
protected static $itemTableName = 'Items';
|
||||||
|
|
||||||
|
protected $wishes;
|
||||||
|
protected $circulations;
|
||||||
|
protected $oldCirculations;
|
||||||
|
|
||||||
|
protected $attributeNames = 'id login firstName lastName displayName freeOne mail addressId mobilePhone officePhone privatePhone';
|
||||||
|
protected $privateAttributeNames = 'password';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $login Login for the user
|
||||||
|
* @param string $password Password for the user
|
||||||
|
* @return User|null User object if we were able to authenticate
|
||||||
|
*/
|
||||||
|
public static function authenticate($login, $password)
|
||||||
|
{
|
||||||
|
$password = str_replace("'", "''", $password);
|
||||||
|
return User::find($login, " UPPER(password) = UPPER('$password') ", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a user by its login. Do not represent a valid authentication.
|
||||||
|
*
|
||||||
|
* Cond has to be safe because no check are made inside.
|
||||||
|
*
|
||||||
|
* @param string $login login the login name
|
||||||
|
* @param string $cond a condition to restrict the choice, optional
|
||||||
|
* @param bool $raiseError
|
||||||
|
* @return User the User object or NULL if no user found.
|
||||||
|
*/
|
||||||
|
public static function find($login, $cond = '', $raiseError = true)
|
||||||
|
{
|
||||||
|
$login = str_replace("'", "''", $login);
|
||||||
|
if(strlen($cond) > 0) {
|
||||||
|
$cond = " AND $cond";
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = sprintf("SELECT TOP 1
|
||||||
|
[FirstName] AS firstName,
|
||||||
|
[LastName] AS lastName,
|
||||||
|
[DisplayName] AS displayName,
|
||||||
|
[UserDefined1] AS freeOne,
|
||||||
|
[ActualAddressID] AS addressId,
|
||||||
|
[Email] AS mail,
|
||||||
|
[TelephoneMobile] AS mobilePhone,
|
||||||
|
[TelephonePrivate] AS privatePhone,
|
||||||
|
[Telephone] AS officePhone,
|
||||||
|
[%s] AS id,
|
||||||
|
REPLACE(UseraccountNr, ' ', '') AS login
|
||||||
|
FROM [%s] AS u
|
||||||
|
LEFT JOIN [%s] AS a ON a.[%s] = u.[ActualAddressID]
|
||||||
|
WHERE REPLACE(UseraccountNr, ' ', '') = '%s' AND disabled = 1 %s;",
|
||||||
|
self::$idColumn, self::$tableName, self::$addressTableName, self::$addressIdColumn, $login, $cond);
|
||||||
|
|
||||||
|
$results = Connection::execute($sql, $raiseError);
|
||||||
|
return $results->current() !== false ? new User($results->current()) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return $this->displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the database. Note that new user insertion don't work in this implementation.
|
||||||
|
*/
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$strSQL = "UPDATE " . User::$tableName . " SET FirstName = '$this->sql_firstName', LastName = '$this->sql_lastName', ";
|
||||||
|
$strSQL .= "DisplayName = '$this->sql_displayName'";
|
||||||
|
$strSQL .= "WHERE Replace(UseraccountNr, ' ', '') = '$this->sql_login'";
|
||||||
|
Connection::execute($strSQL, true);
|
||||||
|
|
||||||
|
$strSQL = "UPDATE " . User::$addressTableName . " SET Email = '$this->sql_mail', TelephoneMobile = '$this->sql_mobilePhone', ";
|
||||||
|
$strSQL .= "Telephone = '$this->sql_officePhone', TelephonePrivate = '$this->sql_privatePhone' ";
|
||||||
|
$strSQL .= "WHERE " . User::$addressTableName . "." . User::$addressIdColumn . " = $this->sql_addressId";
|
||||||
|
Connection::execute($strSQL, true);
|
||||||
|
|
||||||
|
if ($this->password) {
|
||||||
|
$strSQL = "UPDATE " . User::$tableName . " SET Password = UPPER('$this->sql_password') ";
|
||||||
|
$strSQL .= "WHERE Replace(UseraccountNr, ' ', '') = '$this->sql_login'";
|
||||||
|
Connection::execute($strSQL, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function reload()
|
||||||
|
{
|
||||||
|
$this->setAttributes(User::find($this->login)->toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCirculations()
|
||||||
|
{
|
||||||
|
if (!$this->circulations) {
|
||||||
|
$strSQL = "SELECT NoticeId, CheckOutDate, ItemNr FROM Circulations, Items " .
|
||||||
|
"WHERE Circulations.UseraccountId = $this->id and Items.ItemId=Circulations.ItemId " .
|
||||||
|
"ORDER BY ItemNr asc";
|
||||||
|
|
||||||
|
$result = Connection::execute($strSQL);
|
||||||
|
|
||||||
|
$ids = array();
|
||||||
|
$checkOutDates = array();
|
||||||
|
$itemNrs = array();
|
||||||
|
|
||||||
|
while ($row = $result->next()) {
|
||||||
|
$ids[] = $row['NoticeId'];
|
||||||
|
$checkOutDates[] = $row['CheckOutDate'];
|
||||||
|
$itemNrs[] = $row['ItemNr'];
|
||||||
|
}
|
||||||
|
$this->circulations = AudioBook::find($ids);
|
||||||
|
|
||||||
|
// ici je remplace le champs date du livre par la date du prêt
|
||||||
|
$counter = 0;
|
||||||
|
foreach ($this->circulations as &$circulation) {
|
||||||
|
|
||||||
|
$circulation->date = substr($checkOutDates[$counter], 0, 10);
|
||||||
|
$circulation->itemNr = $itemNrs[$counter];
|
||||||
|
|
||||||
|
$counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->circulations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOldCirculations()
|
||||||
|
{
|
||||||
|
|
||||||
|
//if(!$this->oldCirculations){
|
||||||
|
$strSQL = "SELECT NoticeId, CheckOutDate FROM OldCirculations, Items " .
|
||||||
|
"WHERE OldCirculations.UseraccountId = $this->id and Items.ItemId=OldCirculations.ItemId " .
|
||||||
|
"ORDER BY CheckOutDate desc";
|
||||||
|
|
||||||
|
|
||||||
|
$result = Connection::execute($strSQL);
|
||||||
|
$ids = array();
|
||||||
|
$checkOutDates = array();
|
||||||
|
while ($row = $result->next()) {
|
||||||
|
$ids[] = $row['NoticeId'];
|
||||||
|
$checkOutDates[] = $row['CheckOutDate'];
|
||||||
|
}
|
||||||
|
$this->oldCirculations = AudioBook::find($ids);
|
||||||
|
|
||||||
|
// ici je remplace le champs date du livre par la date du prêt
|
||||||
|
$counter = 0;
|
||||||
|
foreach ($this->oldCirculations as &$circulation) {
|
||||||
|
|
||||||
|
$circulation->date = substr($checkOutDates[$counter], 0, 10);
|
||||||
|
$counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
return $this->oldCirculations;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a book to the wish list if it is not already inside.
|
||||||
|
*
|
||||||
|
* delete the wishes cache for it to be reloaded the next time getWishes will be called.
|
||||||
|
* @param int $noticeId
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function addWish($noticeId)
|
||||||
|
{
|
||||||
|
$noticeId = str_replace("'", "''", $noticeId);
|
||||||
|
if (!$this->hasWish($noticeId)) {
|
||||||
|
// recover last id
|
||||||
|
$idSQL = "SELECT WishID from Counters";
|
||||||
|
$idResult = Connection::execute($idSQL, true);
|
||||||
|
// return print_r($idResult, 1);
|
||||||
|
if ($row = $idResult->next()) {
|
||||||
|
// get new value
|
||||||
|
$newWishID = $row['WishID'] + 1;
|
||||||
|
|
||||||
|
// update counter
|
||||||
|
$idSQL = "UPDATE Counters SET WishID=" . $newWishID;
|
||||||
|
Connection::execute($idSQL, true);
|
||||||
|
|
||||||
|
$table = User::$wishTableName;
|
||||||
|
$employee_id = Configuration::get('www_employee_id');
|
||||||
|
$library_id = Configuration::get('www_library_id');
|
||||||
|
$strSQL = "INSERT INTO $table (WishID, " . AudioBook::$idColumn . ", " . User::$idColumn . ", CreationDate, EmployeeID, BranchOfficeID, Remark, ModificationDate)";
|
||||||
|
$strSQL .= " VALUES($newWishID, $noticeId, $this->id, GETDATE(), $employee_id, $library_id, '', GETDATE())";
|
||||||
|
|
||||||
|
// return $strSQL;
|
||||||
|
Connection::execute($strSQL);
|
||||||
|
|
||||||
|
// $this->wishes = NULL;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the book is in the wish list
|
||||||
|
* @param int $noticeId
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasWish($noticeId)
|
||||||
|
{
|
||||||
|
foreach ($this->getWishes() as $book) {
|
||||||
|
if ($book->id == $noticeId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wishes are all the books that this user want to read.
|
||||||
|
* @param int $limit
|
||||||
|
* @return AudioBook[]
|
||||||
|
*/
|
||||||
|
public function getWishes($limit = 50)
|
||||||
|
{
|
||||||
|
if (!$this->wishes) {
|
||||||
|
$strSQL = "SELECT TOP " . $limit . AudioBook::$idColumn . " FROM " . User::$wishTableName . " WHERE " . User::$idColumn . " = $this->id ORDER BY CreationDate desc";
|
||||||
|
|
||||||
|
$result = Connection::execute($strSQL);
|
||||||
|
$ids = array();
|
||||||
|
while ($row = $result->next()) {
|
||||||
|
$ids[] = $row['NoticeID'];
|
||||||
|
}
|
||||||
|
$this->wishes = AudioBook::find($ids);
|
||||||
|
}
|
||||||
|
return $this->wishes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a book from the wish list
|
||||||
|
* @param int $noticeId
|
||||||
|
*/
|
||||||
|
public function deleteWish($noticeId)
|
||||||
|
{
|
||||||
|
$noticeId = str_replace("'", "''", $noticeId);
|
||||||
|
$table = User::$wishTableName;
|
||||||
|
$strSQL = "DELETE FROM $table";
|
||||||
|
$strSQL .= " WHERE " . AudioBook::$idColumn . " = $noticeId AND " . User::$idColumn . " = $this->id;";
|
||||||
|
Connection::execute($strSQL, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
402
mobile.netbiblio.php
Normal file
402
mobile.netbiblio.php
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright Mathieu Schroeter for the BSR, 2013
|
||||||
|
* Modif Simon Schulé pour la BSR, 2013. 2014
|
||||||
|
* Copyright Gilles Crettenand for the BSR, 2015
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once "global.php";
|
||||||
|
require_once "lib/AudioBook.php";
|
||||||
|
require_once "lib/User.php";
|
||||||
|
require_once "lib/BookSearch.php";
|
||||||
|
|
||||||
|
require_once "mobile.webservice.php";
|
||||||
|
|
||||||
|
class NetBiblio extends WebService
|
||||||
|
{
|
||||||
|
private $data = array();
|
||||||
|
|
||||||
|
private $login = '';
|
||||||
|
private $client = 'website';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $IP
|
||||||
|
* @param $client
|
||||||
|
* @param $login
|
||||||
|
* @param $code
|
||||||
|
* @throws SqlException
|
||||||
|
*/
|
||||||
|
public function AddDownloadLog($IP, $client, $login, $code)
|
||||||
|
{
|
||||||
|
$this->data = array();
|
||||||
|
|
||||||
|
$client = str_replace("'", "", $client);
|
||||||
|
$login = str_replace("'", "", $login);
|
||||||
|
$code = ltrim(str_replace("'", "", $code), '0');
|
||||||
|
$itemNr = $code . 'V';
|
||||||
|
$itemId = '';
|
||||||
|
$userId = '';
|
||||||
|
|
||||||
|
/* Récupération de l'id de l'exemplaire */
|
||||||
|
$sql = "SELECT itemID from Netbiblio3.dbo.items where ltrim(rtrim(itemnr))='$itemNr';";
|
||||||
|
$result = Connection::execute($sql, false);
|
||||||
|
|
||||||
|
if ($row = $result->next()) {
|
||||||
|
$itemId = $row['itemID'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Récupération de l'id du compte */
|
||||||
|
$sql = "SELECT useraccountID from Netbiblio3.dbo.UserAccounts where ltrim(rtrim(useraccountnr))='$login';";
|
||||||
|
$result = Connection::execute($sql, false);
|
||||||
|
if ($row = $result->next()) {
|
||||||
|
$userId = $row['useraccountID'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "SELECT circulationId from Netbiblio3.dbo.OldCirculations where useraccountID=$userId AND itemID=$itemId AND ltrim(rtrim(remark))='$client';";
|
||||||
|
$result = Connection::execute($sql, false);
|
||||||
|
|
||||||
|
if ($existingEntry = $result->next()) {
|
||||||
|
$existingId = $existingEntry['circulationId'];
|
||||||
|
$logSql = "UPDATE OldCirculations SET CheckInDate=GETDATE(), CheckOutDate=GETDATE() WHERE circulationID=$existingId";
|
||||||
|
} else {
|
||||||
|
$sql = "SELECT TOP 1 circulationID FROM oldcirculations ORDER BY CirculationID DESC";
|
||||||
|
$result = Connection::execute($sql, false);
|
||||||
|
if ($row = $result->next()) {
|
||||||
|
$nextId = $row['circulationID'] + 1;
|
||||||
|
} else {
|
||||||
|
$nextId = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ajout d'un ancien prêt dans OldCirculations */
|
||||||
|
$worker_id = Configuration::get('netbiblio_worker_id');
|
||||||
|
$logSql = "INSERT INTO Netbiblio3.dbo.OldCirculations (" .
|
||||||
|
" CirculationID, " .
|
||||||
|
" ItemID, " .
|
||||||
|
" UseraccountID, " .
|
||||||
|
" DueDate, " .
|
||||||
|
" Remark, " .
|
||||||
|
" CheckOutDate, " .
|
||||||
|
" CheckOutBranchofficeID, " .
|
||||||
|
" CheckOutEmployeeID, " .
|
||||||
|
" CheckInDate, " .
|
||||||
|
" CheckInBranchofficeID, " .
|
||||||
|
" CheckInEmployeeID, " .
|
||||||
|
" Reminders, " .
|
||||||
|
" Renewals, " .
|
||||||
|
" Prereminder, " .
|
||||||
|
" InfoCode, " .
|
||||||
|
" CheckOutSIP2Info, " .
|
||||||
|
" CheckInSIP2Info " .
|
||||||
|
") VALUES ( " .
|
||||||
|
" $nextId, " .
|
||||||
|
" $itemId, " .
|
||||||
|
" $userId, " .
|
||||||
|
" DATEADD(month, 2, GETDATE()), " .
|
||||||
|
" '$client', " .
|
||||||
|
" GETDATE(), " .
|
||||||
|
" 2, " .
|
||||||
|
" $worker_id, " .
|
||||||
|
" GETDATE(), " .
|
||||||
|
" 2, " .
|
||||||
|
" $worker_id, " .
|
||||||
|
" 0, " .
|
||||||
|
" 0, " .
|
||||||
|
" 1, " .
|
||||||
|
" '-', " .
|
||||||
|
" 1, " .
|
||||||
|
" 1 " .
|
||||||
|
");";
|
||||||
|
|
||||||
|
/* Incrément du compteur de prêts "Circulations" dans Items (exemplaires) */
|
||||||
|
$incrementUserCountersSQL =
|
||||||
|
"UPDATE Useraccounts " .
|
||||||
|
"SET Circulations=Circulations+1, TotalCirculations=TotalCirculations+1 " .
|
||||||
|
"WHERE UseraccountID=$userId;";
|
||||||
|
Connection::execute($incrementUserCountersSQL);
|
||||||
|
|
||||||
|
/* Incrément du compteur de prêts "TotalCirculations" dans UserAccounts (comptes auditeurs) */
|
||||||
|
$incrementItemCountersSQL =
|
||||||
|
"UPDATE Items " .
|
||||||
|
"SET Circulations=Circulations+1, TotalCirculations=TotalCirculations+1 " .
|
||||||
|
"WHERE ItemID=$itemId;";
|
||||||
|
Connection::execute($incrementItemCountersSQL);
|
||||||
|
}
|
||||||
|
Connection::execute($logSql);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Authenticate($login, $password, $client = "website")
|
||||||
|
{
|
||||||
|
session_unset(); /* destroy all session vars */
|
||||||
|
|
||||||
|
$user = User::authenticate($login, $password);
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
throw new WebException ("AuthenticateBad", "authentication failed", -100);
|
||||||
|
}
|
||||||
|
|
||||||
|
$_SESSION["user"]["login"] = $login;
|
||||||
|
$_SESSION["user"]["client"] = $client;
|
||||||
|
|
||||||
|
$this->data = $user->toArray();
|
||||||
|
$this->login = $login;
|
||||||
|
$this->client = $client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Disconnect()
|
||||||
|
{
|
||||||
|
$this->data = array();
|
||||||
|
$_SESSION = array();
|
||||||
|
|
||||||
|
if (ini_get("session.use_cookies")) {
|
||||||
|
$params = session_get_cookie_params();
|
||||||
|
setcookie(session_name(), '', time() - 42000,
|
||||||
|
$params["path"], $params["domain"],
|
||||||
|
$params["secure"], $params["httponly"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function IsAuthenticated()
|
||||||
|
{
|
||||||
|
$this->data = $this->getUser()->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds entries to OldCirculations in Netbiblio database and increments counters on items and useraccounts tables
|
||||||
|
* For now, keeps a separate log in BSRDownload Database to store IPs
|
||||||
|
* In case a download has already been logged, only the date of the existing entry is updated, no counter incremented.
|
||||||
|
* @param string $login
|
||||||
|
* @return User
|
||||||
|
* @throws WebException in case the login cannot be found in the database
|
||||||
|
*/
|
||||||
|
private function getUser($login = null)
|
||||||
|
{
|
||||||
|
if (!$login) {
|
||||||
|
$login = $_SESSION["user"]["login"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->checkSession($login);
|
||||||
|
$user = User::find($this->login);
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
throw new WebException ("UserNotFound", "cannot find account", -130);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function CheckSession($login = null, $client = 'website')
|
||||||
|
{
|
||||||
|
if (!isset ($_SESSION["user"]["login"])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$login) {
|
||||||
|
$login = $_SESSION["user"]["login"];
|
||||||
|
} else if ($_SESSION["user"]["login"] !== $login) {
|
||||||
|
throw new WebException ("CheckSessionBadAuth", "bad authentication", -1001);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->login = $login;
|
||||||
|
$this->client = $client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function FindAccount($login)
|
||||||
|
{
|
||||||
|
$this->data = $this->getUser($login)->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetWishes()
|
||||||
|
{
|
||||||
|
$books = $this->getUser()->getWishes();
|
||||||
|
$this->data = array_map(array($this, 'AddFiles'), $books);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetCirculations()
|
||||||
|
{
|
||||||
|
$circulations = $this->getUser()->getCirculations();
|
||||||
|
$this->data = array_map(array($this, 'AddFiles'), $circulations);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetOldCirculations()
|
||||||
|
{
|
||||||
|
$circulations = $this->getUser()->getOldCirculations();
|
||||||
|
$this->data = array_map(array($this, 'AddFiles'), $circulations);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function AddWish($bookNr)
|
||||||
|
{
|
||||||
|
$bookNr = intval($bookNr);
|
||||||
|
$bookId = AudioBook::findIdByCode($bookNr);
|
||||||
|
$this->data[] = $this->getUser()->addWish($bookId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function DeleteWish($bookNr)
|
||||||
|
{
|
||||||
|
$bookNr = intval($bookNr);
|
||||||
|
$bookId = AudioBook::findIdByCode($bookNr);
|
||||||
|
$this->getUser()->deleteWish($bookId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function FindBooks($codes)
|
||||||
|
{
|
||||||
|
$this->CheckSession();
|
||||||
|
|
||||||
|
$codeList = array_map('intval', json_decode($codes, true));
|
||||||
|
foreach ($codeList as $code) {
|
||||||
|
if ($code != 0) {
|
||||||
|
$id = AudioBook::findIdByCode($code);
|
||||||
|
$this->data[] = $this->AddFiles(AudioBook::find($id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function AddFiles(AudioBook $book)
|
||||||
|
{
|
||||||
|
$book = $book->toArray();
|
||||||
|
|
||||||
|
$uri = sprintf("%s%s",
|
||||||
|
Configuration::get('checkfile_url'),
|
||||||
|
http_build_query(array(
|
||||||
|
"client" => $this->client,
|
||||||
|
"login" => $this->login,
|
||||||
|
"book" => intval($book['code'])
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
$ch = curl_init($uri);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||||
|
$json = curl_exec($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
$files = json_decode($json, true);
|
||||||
|
if (is_array($files)) {
|
||||||
|
$book['files'] = $files;
|
||||||
|
}
|
||||||
|
return $book;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function FindBook($code)
|
||||||
|
{
|
||||||
|
$this->CheckSession();
|
||||||
|
|
||||||
|
$code = intval($code);
|
||||||
|
$id = AudioBook::findIdByCode($code);
|
||||||
|
$this->data = $this->AddFiles(AudioBook::find($id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Search($query, $start, $limit)
|
||||||
|
{
|
||||||
|
$query = array(
|
||||||
|
'queryText' => $query,
|
||||||
|
'count' => $limit,
|
||||||
|
'page' => ($start / $limit),
|
||||||
|
);
|
||||||
|
$this->NewSearch(json_encode($query));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function NewSearch($values)
|
||||||
|
{
|
||||||
|
$this->CheckSession();
|
||||||
|
|
||||||
|
$queryArray = json_decode($values, true);
|
||||||
|
if(! is_array($queryArray)) {
|
||||||
|
throw new WebException("CallArg", "Argument must be valid JSON.", -42);
|
||||||
|
}
|
||||||
|
|
||||||
|
$bs = new BookSearch();
|
||||||
|
|
||||||
|
if (isset($queryArray['queryType'])) {
|
||||||
|
$bs->addSortField('author_s', SolrQuery::ORDER_ASC);
|
||||||
|
$bs->addSortField('title_s', SolrQuery::ORDER_ASC);
|
||||||
|
$bs->addSortField('producer');
|
||||||
|
$bs->addSortField('mediatype', SolrQuery::ORDER_ASC);
|
||||||
|
} else {
|
||||||
|
$bs->addSortField('availabilitydate');
|
||||||
|
$bs->addSortField('author_s', SolrQuery::ORDER_ASC);
|
||||||
|
$bs->addSortField('title_s', SolrQuery::ORDER_ASC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($queryArray['queryText']) && strlen($queryArray['queryText']) > 0) {
|
||||||
|
$bs->addQuery($queryArray['queryText'], $queryArray['queryType']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($queryArray['reader']) && strlen($queryArray['reader']) > 0) {
|
||||||
|
$bs->addQuery($queryArray['reader'], 'reader');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($queryArray['category']) && is_array($queryArray['category'])) {
|
||||||
|
$selectedCategories = array_filter($queryArray['category'], function ($c) {
|
||||||
|
return $c != '0';
|
||||||
|
});
|
||||||
|
if (count($selectedCategories) > 0) {
|
||||||
|
$selectedCategories = array_map(function ($c) {
|
||||||
|
return "categorycode: $c";
|
||||||
|
}, $selectedCategories);
|
||||||
|
$bs->addQuery('(' . implode(' OR ', $selectedCategories) . ')');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($queryArray['producer']) && strlen($queryArray['producer']) > 0) {
|
||||||
|
$bs->addQuery($queryArray['producer'], 'producer');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($queryArray['jeunesse']) && $queryArray['jeunesse']['filtrer'] === 'filtrer') {
|
||||||
|
$bs->addQuery(1, 'jeunesse');
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = isset($queryArray['count']) ? (int) $queryArray['count'] : Configuration::get('solr.result_count');
|
||||||
|
$start = isset($queryArray['page']) ? $queryArray['page'] * $count : 0;
|
||||||
|
|
||||||
|
$results = $bs->getResults($start, $count);
|
||||||
|
|
||||||
|
$this->data['count'] = $results['response']['numFound'];
|
||||||
|
$this->data['facets'] = $results['facet_counts']['facet_fields'];
|
||||||
|
|
||||||
|
foreach ($results['response']['docs'] as $doc) {
|
||||||
|
$book = AudioBook::find($doc['id']);
|
||||||
|
if($book) {
|
||||||
|
$this->data[] = $this->AddFiles($book);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ListOfReaders()
|
||||||
|
{
|
||||||
|
$this->data = AudioBook::listOfReaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ListOfCategories()
|
||||||
|
{
|
||||||
|
$this->data = AudioBook::listOfCategories();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ListOfTypes()
|
||||||
|
{
|
||||||
|
$this->data = array_filter(AudioBook::listOfTypes(), function ($t) {
|
||||||
|
return strlen($t) > 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function LastBooksByType($type, $itemsByGroup)
|
||||||
|
{
|
||||||
|
$this->checkSession();
|
||||||
|
|
||||||
|
$books = AudioBook::lastBooksByType($type, $itemsByGroup);
|
||||||
|
$books = array_map(array($this, 'AddFiles'), $books);
|
||||||
|
foreach ($books as $book) {
|
||||||
|
$this->data[$book['type']][] = $book;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function InReadingBooks()
|
||||||
|
{
|
||||||
|
$this->data = AudioBook::inReading();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function Output()
|
||||||
|
{
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
6
mobile.php
Normal file
6
mobile.php
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once "mobile.netbiblio.php";
|
||||||
|
|
||||||
|
$web = new NetBiblio();
|
||||||
|
$web->Run();
|
||||||
109
mobile.webservice.php
Normal file
109
mobile.webservice.php
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class WebException extends Exception
|
||||||
|
{
|
||||||
|
private $excname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @param string $reason
|
||||||
|
* @param int $code
|
||||||
|
*/
|
||||||
|
function __construct($name, $reason, $code)
|
||||||
|
{
|
||||||
|
$this->excname = $name;
|
||||||
|
parent::__construct($reason, $code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->excname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class WebService
|
||||||
|
{
|
||||||
|
private $func = null;
|
||||||
|
|
||||||
|
private $log = '';
|
||||||
|
|
||||||
|
public function log($message, $withTime = false) {
|
||||||
|
if($withTime) {
|
||||||
|
$message = date("d-m-Y h:m:s").' '.$message;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->log .= $message."\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Run()
|
||||||
|
{
|
||||||
|
$this->log("------------------");
|
||||||
|
$this->log("Start request", true);
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->Call();
|
||||||
|
$data["result"][$this->func] = $this->Output();
|
||||||
|
} catch (WebException $e) {
|
||||||
|
$data["error"]["code"] = $e->getCode();
|
||||||
|
$data["error"]["name"] = $e->getName();
|
||||||
|
$data["error"]["reason"] = $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->Send($data);
|
||||||
|
|
||||||
|
$this->log("Request finished", true);
|
||||||
|
$this->log("------------------\n\n");
|
||||||
|
|
||||||
|
if(Configuration::get('log.active')) {
|
||||||
|
file_put_contents(Configuration::get('log.file'), $this->log, FILE_APPEND | LOCK_EX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function Call()
|
||||||
|
{
|
||||||
|
ob_start();
|
||||||
|
session_save_path(Configuration::get('session.save_path'));
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
$params = empty($_GET) ? $_POST : $_GET;
|
||||||
|
if (empty($params)) {
|
||||||
|
throw new WebException ("CallArgument", "arguments error", -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!array_key_exists("func", $params)) {
|
||||||
|
throw new WebException ("CallArgFunction", "no 'func' specified", -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->func = $params["func"];
|
||||||
|
unset($params['func']);
|
||||||
|
|
||||||
|
if (!is_callable(array($this, $this->func))) {
|
||||||
|
throw new WebException ("CallFunction", "'func' method not available", -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rm = new ReflectionMethod ($this, $this->func);
|
||||||
|
$nbParams = count($params);
|
||||||
|
$nbArgsFix = $rm->getNumberOfRequiredParameters();
|
||||||
|
$nbArgs = $rm->getNumberOfParameters();
|
||||||
|
|
||||||
|
/* Check the number of arguments. */
|
||||||
|
if ($nbArgs != $nbParams && $nbArgsFix != $nbParams) {
|
||||||
|
throw new WebException ("CallArgNumber", "you must provide " . $nbArgsFix . " arguments", 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->log("Calling '".$this->func."'");
|
||||||
|
call_user_func_array(array($this, $this->func), $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected function Output();
|
||||||
|
|
||||||
|
private function Send(array $data)
|
||||||
|
{
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
$this->log("Data: ".print_r($data, true));
|
||||||
|
echo json_encode($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user