initial commit
This commit is contained in:
194
Connection.php
Normal file
194
Connection.php
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BSR\Lib\db;
|
||||||
|
|
||||||
|
use BSR\Lib\Configuration;
|
||||||
|
use BSR\Lib\Exception\SqlException;
|
||||||
|
|
||||||
|
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,%s;Database=%s;",
|
||||||
|
Configuration::get('db.driver'),
|
||||||
|
Configuration::get('db.server'),
|
||||||
|
Configuration::get('db.port'),
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
final private function __clone() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OdbcResultSet implements \Iterator, \ArrayAccess
|
||||||
|
{
|
||||||
|
public $length;
|
||||||
|
|
||||||
|
private $results;
|
||||||
|
private $error;
|
||||||
|
private $num_fields;
|
||||||
|
private $num_rows;
|
||||||
|
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);
|
||||||
|
$this->num_rows = odbc_num_rows($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 get_num_rows()
|
||||||
|
{
|
||||||
|
return $this->num_rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
63
DbHelper.php
Normal file
63
DbHelper.php
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BSR\Lib\db;
|
||||||
|
|
||||||
|
class DbHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Retrieve the list of all type available in the database.
|
||||||
|
* @param boolean $withJeunesse add 'Jeunesse' to the list
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function ListOfGenres($withJeunesse = false)
|
||||||
|
{
|
||||||
|
$sql = "SELECT DISTINCT
|
||||||
|
LTRIM(RTRIM(Codes.Code)) as code,
|
||||||
|
LTRIM(RTRIM(Codes.TextFre)) AS text
|
||||||
|
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 Codes.TextFre !=''
|
||||||
|
AND Notices.MediaType1Code = 'CDD'
|
||||||
|
ORDER BY text;";
|
||||||
|
|
||||||
|
|
||||||
|
$results = Connection::execute($sql)->to_array();
|
||||||
|
|
||||||
|
if($withJeunesse) {
|
||||||
|
array_unshift($results, array('code' => 'J', 'text' => 'Jeunesse'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the list of all books currently lent 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
117
DbMapping.php
Normal file
117
DbMapping.php
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BSR\Lib\db;
|
||||||
|
|
||||||
|
use BSR\Lib\Exception\InvalidAttributeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 against 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 wishes
|
||||||
|
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
330
User.php
Normal file
330
User.php
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BSR\Lib\db;
|
||||||
|
|
||||||
|
use BSR\Lib\Configuration;
|
||||||
|
use BSR\Lib\Search\BookSearch;
|
||||||
|
use BSR\Lib\Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
[UserAccountID] AS id,
|
||||||
|
REPLACE(UserAccountNr, ' ', '') AS login
|
||||||
|
FROM [UserAccounts] AS u
|
||||||
|
LEFT JOIN [Addresses] AS a ON a.[AddressID] = u.[ActualAddressID]
|
||||||
|
WHERE LTRIM(RTRIM(UserAccountNr)) = '%s' AND disabled = 1 %s AND CategoryCode in ('A', 'M', 'G', 'D', 'I', 'EMP');",
|
||||||
|
$login, $cond);
|
||||||
|
|
||||||
|
$results = Connection::execute($sql, $raiseError);
|
||||||
|
return $results->current() !== false ? new User($results->current()) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Circulations as needed for the BSR internal tools
|
||||||
|
*/
|
||||||
|
public function GetCirculations()
|
||||||
|
{
|
||||||
|
$sql = sprintf("SELECT
|
||||||
|
n.NoticeID,
|
||||||
|
ItemNr,
|
||||||
|
LTRIM(RTRIM(n.NoticeNr)) AS code,
|
||||||
|
LTRIM(RTRIM(n.Title)) AS Title,
|
||||||
|
LTRIM(RTRIM(n.Author)) AS author,
|
||||||
|
Fields.[300] AS media,
|
||||||
|
Fields.[901] AS readBy
|
||||||
|
FROM Circulations AS c
|
||||||
|
INNER JOIN Items AS i ON i.ItemId = c.ItemId
|
||||||
|
INNER JOIN Notices AS n ON n.NoticeID = i.NoticeID
|
||||||
|
LEFT OUTER JOIN (
|
||||||
|
SELECT *
|
||||||
|
FROM (
|
||||||
|
SELECT
|
||||||
|
NoticeID,
|
||||||
|
Tag AS Field,
|
||||||
|
NoticeFields.ContentShortPart AS Data
|
||||||
|
FROM NoticeFields
|
||||||
|
WHERE Tag IN ('901', '300')
|
||||||
|
) AS src
|
||||||
|
PIVOT (
|
||||||
|
MIN(Data)
|
||||||
|
FOR Field IN ([901], [300])
|
||||||
|
) AS pvt
|
||||||
|
) Fields ON n.NoticeID = Fields.NoticeID
|
||||||
|
WHERE
|
||||||
|
c.UserAccountID = %s
|
||||||
|
ORDER BY ItemNr ASC", $this->id);
|
||||||
|
|
||||||
|
$result = Connection::execute($sql);
|
||||||
|
return $result ? $result->to_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetOldLoansNrs()
|
||||||
|
{
|
||||||
|
$sql = sprintf("SELECT
|
||||||
|
n.NoticeNr
|
||||||
|
FROM OldCirculations AS c
|
||||||
|
INNER JOIN Items AS i ON i.ItemId = c.ItemId
|
||||||
|
INNER JOIN Notices AS n ON n.NoticeID = i.NoticeID
|
||||||
|
WHERE
|
||||||
|
c.UserAccountID = %s AND
|
||||||
|
n.MediaType1Code in ('CDD', 'CDA', 'DVD', 'CDS') AND n.deleted=1
|
||||||
|
ORDER BY ItemNr ASC", $this->id);
|
||||||
|
|
||||||
|
$result = Connection::execute($sql);
|
||||||
|
return $result ? $result->to_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLoansData($table, $sort = "acquisitiondate DESC")
|
||||||
|
{
|
||||||
|
$sql = sprintf("SELECT top 50
|
||||||
|
realn.NoticeId as NoticeID,
|
||||||
|
realn.NoticeNr,
|
||||||
|
CheckOutDate,
|
||||||
|
c.Remark,
|
||||||
|
ItemNr
|
||||||
|
FROM %s AS c
|
||||||
|
INNER JOIN Items AS i ON i.ItemId = c.ItemId
|
||||||
|
INNER JOIN Notices AS lentn ON lentn.NoticeID = i.NoticeID
|
||||||
|
INNER JOIN Notices AS realn ON REPLACE(ltrim(rtrim(lentn.noticenr)), 'V', '') = ltrim(rtrim(realn.noticenr))
|
||||||
|
WHERE
|
||||||
|
c.UserAccountID = %s
|
||||||
|
ORDER BY %s", $table, $this->id, $sort);
|
||||||
|
|
||||||
|
return Connection::execute($sql)->to_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _getLoans($table, $count, $sort)
|
||||||
|
{
|
||||||
|
$circulations = $this->getLoansData($table, $sort);
|
||||||
|
//Logger::log(print_r($circulations, true));
|
||||||
|
// getting the intval of the NoticeNr will remove any 'V' or 'T' and thus we will have no issues with
|
||||||
|
// the virtual books that are used for Downloads and so.
|
||||||
|
$codes = array_unique(array_map(function($c) {
|
||||||
|
return trim($c['NoticeNr']); }, $circulations));
|
||||||
|
|
||||||
|
if($count) {
|
||||||
|
return count($circulations);
|
||||||
|
}
|
||||||
|
|
||||||
|
$books = count($codes) > 0 ? BookSearch::GetBooks($codes) : array();
|
||||||
|
//Logger::log(print_r($books, true));
|
||||||
|
foreach($circulations as $c) {
|
||||||
|
$id = $c['NoticeID'];
|
||||||
|
if(isset($books[$id])) {
|
||||||
|
$books[$id]['checkoutDate'] = $c['CheckOutDate'];
|
||||||
|
$books[$id]['remark'] = $c['Remark'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $books;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loans (Circulations) as needed on the website
|
||||||
|
* @param boolean $count return only the count
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function GetLoans($count = false)
|
||||||
|
{
|
||||||
|
return $this->_getLoans('Circulations', $count, "ItemNr ASC");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Old loans (OldCirculations) as needed on the website
|
||||||
|
* @param boolean $count return only the count
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function GetOldLoans($count = false)
|
||||||
|
{
|
||||||
|
return $this->_getLoans('OldCirculations', $count, 'CheckOutDate DESC');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Books eligible for feedback by the user. Lent or downloaded more than 2 weeks ago and less than 5 monthes.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function GetBooksForFeedback()
|
||||||
|
{
|
||||||
|
$sql = sprintf("SELECT n.NoticeNr
|
||||||
|
FROM OldCirculations AS c
|
||||||
|
INNER JOIN Items AS i ON i.ItemId = c.ItemId
|
||||||
|
INNER JOIN Notices AS n ON n.NoticeID = i.NoticeID
|
||||||
|
WHERE
|
||||||
|
c.UserAccountID = %s
|
||||||
|
AND DATEDIFF(month, CheckOutDate, GETDATE()) < 5
|
||||||
|
", $this->id);
|
||||||
|
|
||||||
|
return Connection::execute($sql)->to_array(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a book to the wish list if it is not already inside.
|
||||||
|
|
||||||
|
* @param string $noticeNr
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function addWish($noticeNr)
|
||||||
|
{
|
||||||
|
if ($this->hasWish($noticeNr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "UPDATE Counters
|
||||||
|
SET WishID = WishID + 1
|
||||||
|
OUTPUT INSERTED.WishID;";
|
||||||
|
$result = Connection::execute($sql, true);
|
||||||
|
$row = $result->current();
|
||||||
|
|
||||||
|
$employee_id = Configuration::get('www_employee_id');
|
||||||
|
$library_id = Configuration::get('www_library_id');
|
||||||
|
$sql = sprintf("INSERT INTO Wishes
|
||||||
|
(WishID, NoticeID, UserAccountID, CreationDate, EmployeeID, BranchOfficeID, Remark, ModificationDate)
|
||||||
|
SELECT %s , NoticeID, %s, GETDATE() , %s , %s , '' , GETDATE()
|
||||||
|
FROM Notices
|
||||||
|
WHERE LTRIM(RTRIM(NoticeNr)) = '%s';",
|
||||||
|
$row['WishID'], $this->id, $employee_id, $library_id, $noticeNr);
|
||||||
|
|
||||||
|
$status = Connection::execute($sql);
|
||||||
|
return $status && ! $status->is_error() && $status->get_num_rows() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the book is in the wish list
|
||||||
|
* @param string $noticeNr
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function hasWish($noticeNr)
|
||||||
|
{
|
||||||
|
$sql = sprintf("SELECT w.NoticeID
|
||||||
|
FROM Wishes AS w
|
||||||
|
INNER JOIN Notices AS n ON n.NoticeID = w.NoticeID
|
||||||
|
WHERE
|
||||||
|
LTRIM(RTRIM(n.NoticeNr)) = '%s'
|
||||||
|
AND w.UserAccountID = %s;", $noticeNr, $this->id);
|
||||||
|
$result = Connection::execute($sql);
|
||||||
|
|
||||||
|
return $result->current() !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wishes are all the books that this user want to read.
|
||||||
|
* @param boolean $count return only the count
|
||||||
|
* @param int $limit
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getWishes($count = false, $limit = 200)
|
||||||
|
{
|
||||||
|
$sql = sprintf("SELECT TOP $limit
|
||||||
|
NoticeID, CreationDate
|
||||||
|
FROM Wishes
|
||||||
|
WHERE UserAccountID = %s
|
||||||
|
ORDER BY CreationDate DESC", $this->id);
|
||||||
|
|
||||||
|
$result = Connection::execute($sql);
|
||||||
|
|
||||||
|
$wishList = $result->to_array();
|
||||||
|
$ids = array_map(function($r) { return $r['NoticeID']; }, $wishList);
|
||||||
|
if($count) {
|
||||||
|
return count($ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
$books = BookSearch::GetBooks($ids, 'id');
|
||||||
|
foreach($wishList as $w) {
|
||||||
|
$id = $w['NoticeID'];
|
||||||
|
if(isset($books[$id])) {
|
||||||
|
$books[$id]['creationDate'] = $w['CreationDate'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$creationDates = array();
|
||||||
|
foreach ($books as $key => $book)
|
||||||
|
{
|
||||||
|
$creationDates[$key] = $book['creationDate'];
|
||||||
|
}
|
||||||
|
array_multisort($creationDates, SORT_DESC, $books);
|
||||||
|
|
||||||
|
return $books;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a book from the wish list
|
||||||
|
* @param string $noticeNr
|
||||||
|
* @return boolean Was the deletion was successful or not ?
|
||||||
|
*/
|
||||||
|
public function deleteWish($noticeNr)
|
||||||
|
{
|
||||||
|
$sql = sprintf("DELETE w
|
||||||
|
FROM Wishes AS w
|
||||||
|
INNER JOIN Notices AS n ON n.NoticeID = w.NoticeID
|
||||||
|
WHERE
|
||||||
|
LTRIM(RTRIM(n.NoticeNr)) = '%s'
|
||||||
|
AND UserAccountID = %s;", $noticeNr, $this->id);
|
||||||
|
$status = Connection::execute($sql, true);
|
||||||
|
return $status && ! $status->is_error() && $status->get_num_rows() > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
33
composer.json
Normal file
33
composer.json
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name" : "bsr/callioapi",
|
||||||
|
"description" : "Implementation of bsr/webservice as Callioplayer server api",
|
||||||
|
"repositories" : [
|
||||||
|
{
|
||||||
|
"type" : "vcs",
|
||||||
|
"url" : "https://usrpath@bitbucket.org/usrpath/webservice.git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "vcs",
|
||||||
|
"url" : "https://usrpath@bitbucket.org/usrpath/bsrdb.git"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"authors" : [
|
||||||
|
{
|
||||||
|
"name" : "Simon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "Guillermo"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require" : {
|
||||||
|
"bsr/webservice" : "self.version",
|
||||||
|
"bsr/db" : "self.version"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {"BSR\\CallioApi\\" : "src/"}
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"pds/skeleton": "^1.0",
|
||||||
|
"phpunit/phpunit": "^6"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user