change line endings

master
Gilles Crettenand 11 years ago
parent 265ed19543
commit c0159f4b79

8
.gitignore vendored

@ -1,4 +1,4 @@
.idea .idea
logs/ logs/
*configuration.local.php *configuration.local.php
*~ *~

@ -1,106 +1,106 @@
<?php <?php
namespace BSR\Lib; namespace BSR\Lib;
class Configuration { class Configuration {
private static $instance = null; private static $instance = null;
/** /**
* ! WARNING ! * ! WARNING !
* *
* Those are default values, if you need to change them for a particular host, * 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 * please just create a file named 'configuration.local.php' in the same directory
* and redefine the values there ! * and redefine the values there !
* *
* This file must contain an array named $configuration containing the keys you * 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 * want to redefine. Then, those values will be used to replace those in the
* array defined just below. * array defined just below.
* *
* @var array configuration values * @var array configuration values
*/ */
private $values = array( private $values = array(
'db' => array( 'db' => array(
'driver' => 'SQL Server Native Client 11.0', 'driver' => 'SQL Server Native Client 11.0',
'server' => 'BSR2012\SQLEXPRESS', 'server' => 'BSR2012\SQLEXPRESS',
'port' => '1433', 'port' => '1433',
'username' => 'alcoda', 'username' => 'alcoda',
'password' => 'alcodaonly', 'password' => 'alcodaonly',
'name' => 'NetBiblio3', 'name' => 'NetBiblio3',
), ),
'solr' => array( 'solr' => array(
'server' => '192.168.1.250', 'server' => '192.168.1.250',
'port' => '8983', 'port' => '8983',
'username' => '', 'username' => '',
'password' => '', 'password' => '',
'path' => 'solr/bsr1', 'path' => 'solr/bsr1',
'result_count' => 10, 'result_count' => 10,
), ),
'log' => array( 'log' => array(
'file' => 'C:\inetpub\wwwroot\WebService\logs\log.txt', 'file' => 'C:\inetpub\wwwroot\WebService\logs\log.txt',
// The greater the verbosity, the more is displayed // The greater the verbosity, the more is displayed
// 0 : no log at all // 0 : no log at all
// 1 : log function calls and errors // 1 : log function calls and errors
// 2 : log parameters and sent data // 2 : log parameters and sent data
'verbosity' => 0, 'verbosity' => 0,
), ),
'session' => array( 'session' => array(
'save_path' => '' 'save_path' => ''
), ),
'checkfile_url' => 'http://fichiers.bibliothequesonore.ch/checkfile.php?', 'checkfile_url' => 'http://fichiers.bibliothequesonore.ch/checkfile.php?',
'netbiblio_worker_id' => 45, 'netbiblio_worker_id' => 45,
'www_employee_id' => 45, 'www_employee_id' => 45,
'www_library_id' => 2, 'www_library_id' => 2,
); );
private $custom_config = 'configuration.local.php'; private $custom_config = 'configuration.local.php';
private function __construct() { private function __construct() {
// by default, set the session save path to the default value; // by default, set the session save path to the default value;
$this->values['session']['save_path'] = session_save_path(); $this->values['session']['save_path'] = session_save_path();
if(file_exists($this->custom_config)) { if(file_exists($this->custom_config)) {
require_once($this->custom_config); require_once($this->custom_config);
if(! isset($configuration) || ! is_array($configuration)) { 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."); 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); $this->values = array_replace_recursive($this->values, $configuration);
} }
} }
private function dotNotationAccess($data, $key, $default=null) private function dotNotationAccess($data, $key, $default=null)
{ {
$keys = explode('.', $key); $keys = explode('.', $key);
foreach ($keys as $k) { foreach ($keys as $k) {
if (!is_array($data)) { if (!is_array($data)) {
throw new \Exception("Try to access non-array as array, key '$key''"); throw new \Exception("Try to access non-array as array, key '$key''");
} }
if (!isset($data[$k])) { if (!isset($data[$k])) {
return $default; return $default;
} }
$data = $data[$k]; $data = $data[$k];
} }
return $data; return $data;
} }
private function value($name, $default) { private function value($name, $default) {
return $this->dotNotationAccess($this->values, $name, $default); return $this->dotNotationAccess($this->values, $name, $default);
} }
/** /**
* @param $name * @param $name
* @param mixed $default the default value for your configuration option * @param mixed $default the default value for your configuration option
* @return mixed return the configuration value if the key is find, the default otherwise * @return mixed return the configuration value if the key is find, the default otherwise
*/ */
public static function get($name, $default = null) { public static function get($name, $default = null) {
if(is_null(self::$instance)) { if(is_null(self::$instance)) {
self::$instance = new Configuration(); self::$instance = new Configuration();
} }
return self::$instance->value($name, $default); return self::$instance->value($name, $default);
} }
} }

@ -1,9 +1,9 @@
<?php <?php
namespace BSR\Lib\Exception; namespace BSR\Lib\Exception;
class BookNotFoundException extends WebException { class BookNotFoundException extends WebException {
public function __construct($code) { public function __construct($code) {
parent::__construct('BookNotFound', "The book with code $code was not found", -404); parent::__construct('BookNotFound', "The book with code $code was not found", -404);
} }
} }

@ -1,8 +1,8 @@
<?php <?php
namespace BSR\Lib\Exception; namespace BSR\Lib\Exception;
/** /**
* Exception raised when an invalid attribute name is accessed * Exception raised when an invalid attribute name is accessed
*/ */
class InvalidAttributeException extends \Exception { } class InvalidAttributeException extends \Exception { }

@ -1,19 +1,19 @@
<?php <?php
namespace BSR\Lib\Exception; namespace BSR\Lib\Exception;
class SqlException extends \Exception class SqlException extends \Exception
{ {
private $query; private $query;
public function __construct($message = "Sql Error", $query = "") public function __construct($message = "Sql Error", $query = "")
{ {
$this->query = $query; $this->query = $query;
parent::__construct($message, 0); parent::__construct($message, 0);
} }
public function getSqlError() public function getSqlError()
{ {
return $this->getMessage().' while executing: '.$this->query; return $this->getMessage().' while executing: '.$this->query;
} }
} }

@ -1,24 +1,24 @@
<?php <?php
namespace BSR\Lib\Exception; namespace BSR\Lib\Exception;
class WebException extends \Exception class WebException extends \Exception
{ {
private $excname; private $excname;
/** /**
* @param string $name * @param string $name
* @param string $reason * @param string $reason
* @param int $code * @param int $code
*/ */
function __construct($name, $reason, $code) function __construct($name, $reason, $code)
{ {
$this->excname = $name; $this->excname = $name;
parent::__construct($reason, $code); parent::__construct($reason, $code);
} }
public function getName() public function getName()
{ {
return $this->excname; return $this->excname;
} }
} }

@ -1,89 +1,89 @@
<?php <?php
namespace BSR\Lib\Search; namespace BSR\Lib\Search;
use BSR\Lib\Configuration; use BSR\Lib\Configuration;
use BSR\Lib\Exception\WebException; use BSR\Lib\Exception\WebException;
mb_http_output('UTF-8'); mb_http_output('UTF-8');
class BookSearch class BookSearch
{ {
/** @var \SolrClient */ /** @var \SolrClient */
private $client; private $client;
/** @var \SolrQuery */ /** @var \SolrQuery */
private $query; private $query;
private $queryParts = array(); private $queryParts = array();
public function __construct() public function __construct()
{ {
$options = array $options = array
( (
'hostname' => Configuration::get('solr.server'), 'hostname' => Configuration::get('solr.server'),
'port' => Configuration::get('solr.port'), 'port' => Configuration::get('solr.port'),
'login' => Configuration::get('solr.username'), 'login' => Configuration::get('solr.username'),
'password' => Configuration::get('solr.password'), 'password' => Configuration::get('solr.password'),
'path' => Configuration::get('solr.path'), 'path' => Configuration::get('solr.path'),
); );
$this->client = new \SolrClient($options); $this->client = new \SolrClient($options);
$this->query = new \SolrQuery(); $this->query = new \SolrQuery();
$this->query->setQuery('*:*'); $this->query->setQuery('*:*');
$this->query->addField('*'); $this->query->addField('*');
$this->query->addParam('q.op', 'AND'); $this->query->addParam('q.op', 'AND');
} }
public function addQuery($queryText, $queryField = null, $escape = true) public function addQuery($queryText, $queryField = null, $escape = true)
{ {
if($escape) { if($escape) {
$queryText = \SolrUtils::escapeQueryChars($queryText); $queryText = \SolrUtils::escapeQueryChars($queryText);
} }
if (strlen($queryField) > 0) { if (strlen($queryField) > 0) {
$queryText = "$queryField:\"$queryText\""; $queryText = "$queryField:\"$queryText\"";
} }
$this->queryParts[] = $queryText; $this->queryParts[] = $queryText;
} }
public function addSortField($field, $order = \SolrQuery::ORDER_DESC) public function addSortField($field, $order = \SolrQuery::ORDER_DESC)
{ {
$this->query->addSortField($field, $order); $this->query->addSortField($field, $order);
} }
/** /**
* @param int $start * @param int $start
* @param int $count * @param int $count
* @return array * @return array
* @throws WebException * @throws WebException
*/ */
public function getResults($start = 0, $count = 15) public function getResults($start = 0, $count = 15)
{ {
if (count($this->queryParts) == 0) if (count($this->queryParts) == 0)
$query = '*:*'; $query = '*:*';
else { else {
$query = implode(' AND ', $this->queryParts); $query = implode(' AND ', $this->queryParts);
} }
$this->query->setQuery($query); $this->query->setQuery($query);
$this->query->setStart($start); $this->query->setStart($start);
$this->query->setRows($count); $this->query->setRows($count);
try { try {
$results = $this->client->query($this->query)->getResponse(); $results = $this->client->query($this->query)->getResponse();
} catch(\SolrClientException $e) { } catch(\SolrClientException $e) {
throw new WebException ("SolrError", $e->getMessage(), -700); throw new WebException ("SolrError", $e->getMessage(), -700);
} }
$books = isset($results['response']['docs']) && $results['response']['docs'] ? $books = isset($results['response']['docs']) && $results['response']['docs'] ?
array_map(function($o) { return (array) $o; }, $results['response']['docs']) : array_map(function($o) { return (array) $o; }, $results['response']['docs']) :
array(); array();
return array( return array(
'count' => $results['response']['numFound'], 'count' => $results['response']['numFound'],
'facets' => $results['facet_counts']['facet_fields'], 'facets' => $results['facet_counts']['facet_fields'],
'books' => $books, 'books' => $books,
); );
} }
} }

@ -1,122 +1,122 @@
<?php <?php
namespace BSR\Lib; namespace BSR\Lib;
use BSR\Lib\Exception\WebException; use BSR\Lib\Exception\WebException;
abstract class WebService abstract class WebService
{ {
private $func = null; private $func = null;
private $status = 200; private $status = 200;
private $log = ''; private $log = '';
/** /**
* @param $message * @param $message
* @param int $verbosity * @param int $verbosity
* @param bool $withTime * @param bool $withTime
*/ */
public function log($message, $verbosity = 1, $withTime = false) { public function log($message, $verbosity = 1, $withTime = false) {
if(Configuration::get('log.verbosity') < $verbosity) { if(Configuration::get('log.verbosity') < $verbosity) {
return; return;
} }
if($withTime) { if($withTime) {
$message = date("d-m-Y h:m:s").' '.$message; $message = date("d-m-Y h:m:s").' '.$message;
} }
$this->log .= $message."\n"; $this->log .= $message."\n";
} }
public function Run() public function Run()
{ {
$this->log("------------------"); $this->log("------------------");
$this->log("Start request", 1, true); $this->log("Start request", 1, true);
$data = array(); $data = array();
try { try {
$result = $this->Call(); $result = $this->Call();
$data["result"][$this->func] = $result; $data["result"][$this->func] = $result;
} catch (WebException $e) { } catch (WebException $e) {
$data["error"]["code"] = $e->getCode(); $data["error"]["code"] = $e->getCode();
$data["error"]["name"] = $e->getName(); $data["error"]["name"] = $e->getName();
$data["error"]["reason"] = $e->getMessage(); $data["error"]["reason"] = $e->getMessage();
$this->status = 400; $this->status = 400;
$this->log(sprintf("Error : [%s] %s", $e->getCode(), $e->getName())); $this->log(sprintf("Error : [%s] %s", $e->getCode(), $e->getName()));
} catch (\Exception $e) { } catch (\Exception $e) {
$data["failure"]["message"] = $e->getMessage(); $data["failure"]["message"] = $e->getMessage();
$this->status = 500; $this->status = 500;
$this->log(sprintf("Failure : %s", $e->getMessage())); $this->log(sprintf("Failure : %s", $e->getMessage()));
} }
$this->Send($data); $this->Send($data);
$this->log("Request finished", 1, true); $this->log("Request finished", 1, true);
$this->log("------------------\n\n"); $this->log("------------------\n\n");
if(Configuration::get('log.verbosity') > 0) { if(Configuration::get('log.verbosity') > 0) {
file_put_contents(Configuration::get('log.file'), $this->log, FILE_APPEND | LOCK_EX); file_put_contents(Configuration::get('log.file'), $this->log, FILE_APPEND | LOCK_EX);
} }
} }
private function Call() private function Call()
{ {
ob_start(); ob_start();
session_save_path(Configuration::get('session.save_path')); session_save_path(Configuration::get('session.save_path'));
session_start(); session_start();
$params = empty($_GET) ? $_POST : $_GET; $params = empty($_GET) ? $_POST : $_GET;
if (empty($params)) { if (empty($params)) {
throw new WebException ("CallArgument", "arguments error", -1); throw new WebException ("CallArgument", "arguments error", -1);
} }
if (!array_key_exists("func", $params)) { if (!array_key_exists("func", $params)) {
throw new WebException ("CallArgFunction", "no 'func' specified", -2); throw new WebException ("CallArgFunction", "no 'func' specified", -2);
} }
$this->func = $params["func"]; $this->func = $params["func"];
unset($params['func']); unset($params['func']);
if (!is_callable(array($this, $this->func))) { if (!is_callable(array($this, $this->func))) {
throw new WebException ("CallFunction", "'func' method not available", -3); throw new WebException ("CallFunction", "'func' method not available", -3);
} }
$rm = new \ReflectionMethod($this, $this->func); $rm = new \ReflectionMethod($this, $this->func);
$nbParams = count($params); $nbParams = count($params);
$nbArgsFix = $rm->getNumberOfRequiredParameters(); $nbArgsFix = $rm->getNumberOfRequiredParameters();
$nbArgs = $rm->getNumberOfParameters(); $nbArgs = $rm->getNumberOfParameters();
/* Check the number of arguments. */ /* Check the number of arguments. */
if ($nbParams < $nbArgsFix) { if ($nbParams < $nbArgsFix) {
throw new WebException ("CallArgNumber", "you must provide at least " . $nbArgsFix . " arguments", 4); throw new WebException ("CallArgNumber", "you must provide at least " . $nbArgsFix . " arguments", 4);
} }
if ($nbParams > $nbArgs) { if ($nbParams > $nbArgs) {
throw new WebException ("CallArgNumber", "you must provide at most " . $nbArgs . " arguments", 4); throw new WebException ("CallArgNumber", "you must provide at most " . $nbArgs . " arguments", 4);
} }
$this->log("Calling '".$this->func."'"); $this->log("Calling '".$this->func."'");
$this->log("Params: ".print_r($params, true), 2); $this->log("Params: ".print_r($params, true), 2);
return call_user_func_array(array($this, $this->func), $params); return call_user_func_array(array($this, $this->func), $params);
} }
private function Send(array $data) private function Send(array $data)
{ {
static $status_messages = array( static $status_messages = array(
200 => 'Ok', 200 => 'Ok',
400 => 'Bad request', 400 => 'Bad request',
404 => 'Not Found', 404 => 'Not Found',
403 => 'Not Authorized', 403 => 'Not Authorized',
500 => 'Server Error', 500 => 'Server Error',
); );
header(sprintf('HTTP/1.0 %s %s', $this->status, $status_messages[$this->status])); header(sprintf('HTTP/1.0 %s %s', $this->status, $status_messages[$this->status]));
ob_clean(); ob_clean();
flush(); flush();
$this->log("Data: ".print_r($data, true), 2); $this->log("Data: ".print_r($data, true), 2);
echo json_encode($data); echo json_encode($data);
} }
} }

@ -1,251 +1,251 @@
<?php <?php
namespace BSR\Lib\db; namespace BSR\Lib\db;
/** /**
* AudioBook is mapped on a Notice from NetBiblio * AudioBook is mapped on a Notice from NetBiblio
* *
* @property string id * @property string id
* @property string sql_id * @property string sql_id
* @property string title * @property string title
* @property string sql_title * @property string sql_title
* @property string author * @property string author
* @property string sql_author * @property string sql_author
* @property string code * @property string code
* @property string sql_code * @property string sql_code
* @property string summary * @property string summary
* @property string sql_summary * @property string sql_summary
* @property string editor * @property string editor
* @property string sql_editor * @property string sql_editor
* @property string media * @property string media
* @property string sql_media * @property string sql_media
* @property string collection * @property string collection
* @property string sql_collection * @property string sql_collection
* @property string isbn * @property string isbn
* @property string sql_isbn * @property string sql_isbn
* @property string reader * @property string reader
* @property string sql_reader * @property string sql_reader
* @property string cover * @property string cover
* @property string sql_cover * @property string sql_cover
* @property string category * @property string category
* @property string sql_category * @property string sql_category
* @property string availabilityDate * @property string availabilityDate
* @property string sql_availabilityDate * @property string sql_availabilityDate
* @property string producerCode * @property string producerCode
* @property string sql_producerCode * @property string sql_producerCode
* @property string producer * @property string producer
* @property string sql_producer * @property string sql_producer
* @property string genre * @property string genre
* @property string sql_genre * @property string sql_genre
* @property string genreCode * @property string genreCode
* @property string sql_genreCode * @property string sql_genreCode
* @property string coverdisplay * @property string coverdisplay
* @property string sql_coverdisplay * @property string sql_coverdisplay
* @property string link * @property string link
* @property string sql_link * @property string sql_link
* @property string linkTitle * @property string linkTitle
* @property string sql_linkTitle * @property string sql_linkTitle
* @property string mediaType * @property string mediaType
* @property string sql_mediaType * @property string sql_mediaType
*/ */
class AudioBook extends DbMapping class AudioBook extends DbMapping
{ {
protected $attributeNames = 'id title author code summary editor media collection isbn reader cover category availabilityDate producerCode producer genre genreCode coverdisplay link linkTitle mediaType'; protected $attributeNames = 'id title author code summary editor media collection isbn reader cover category availabilityDate producerCode producer genre genreCode coverdisplay link linkTitle mediaType';
public static function find($id) { public static function find($id) {
return self::findBy('NoticeID', $id); return self::findBy('NoticeID', $id);
} }
/** /**
* If $id is an array, return an array of book, if it is only one id, return one book * 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. * Load books details only if not an array.
* *
* Beware that this search use the NoticeID, not the NoticeNr, if you need the last one * Beware that this search use the NoticeID, not the NoticeNr, if you need the last one
* use findByCode method instead; * use findByCode method instead;
* *
* @param string $column * @param string $column
* @param int|array $ids * @param int|array $ids
* @param bool $raw results ? * @param bool $raw results ?
* @return AudioBook|AudioBook[]|array * @return AudioBook|AudioBook[]|array
*/ */
public static function findBy($column, $ids, $raw = false) public static function findBy($column, $ids, $raw = false)
{ {
$multiple = true; $multiple = true;
if(! is_array($ids)) { if(! is_array($ids)) {
$ids = array($ids); $ids = array($ids);
$multiple = false; $multiple = false;
} }
// The following query should be maintained in sync with the one in the solr data source. // The following query should be maintained in sync with the one in the solr data source.
$sql = sprintf("SELECT DISTINCT $sql = sprintf("SELECT DISTINCT
Notices.[NoticeID] AS id, Notices.[NoticeID] AS id,
LTRIM(RTRIM(Notices.[Title])) AS title, LTRIM(RTRIM(Notices.[Title])) AS title,
LTRIM(RTRIM(Notices.[Author])) AS author, LTRIM(RTRIM(Notices.[Author])) AS author,
LTRIM(RTRIM(Notices.[NoticeNr])) AS code, LTRIM(RTRIM(Notices.[NoticeNr])) AS code,
Fields.[520] AS summary, Fields.[520] AS summary,
REPLACE(Fields.[260b], ',', '') AS editor, REPLACE(Fields.[260b], ',', '') AS editor,
LEFT(SUBSTRING(Fields.[260c], PATINDEX('%%[0-9]%%', Fields.[260c]), 8000), PATINDEX('%%[^0-9]%%', SUBSTRING(Fields.[260c], PATINDEX('%%[0-9]%%', Fields.[260c]), 8000) + 'X')-1) AS year, LEFT(SUBSTRING(Fields.[260c], PATINDEX('%%[0-9]%%', Fields.[260c]), 8000), PATINDEX('%%[^0-9]%%', SUBSTRING(Fields.[260c], PATINDEX('%%[0-9]%%', Fields.[260c]), 8000) + 'X')-1) AS year,
Fields.[300] AS media, Fields.[300] AS media,
Fields.[490a] AS collection, Fields.[490a] AS collection,
LTRIM(RTRIM(isbn.DisplayText)) AS isbn, LTRIM(RTRIM(isbn.DisplayText)) AS isbn,
Fields.[901] AS reader, Fields.[901] AS reader,
Fields.[899a] AS cover, Fields.[899a] AS cover,
'' AS category, -- supposed to come from tags 600, 610, 650, 651, 655, 690, 691, 695, 696 but always empty anyway '' AS category, -- supposed to come from tags 600, 610, 650, 651, 655, 690, 691, 695, 696 but always empty anyway
item1.AcquisitionDate AS availabilityDate, item1.AcquisitionDate AS availabilityDate,
LTRIM(RTRIM(ProducerCode.TextFre)) As producer, LTRIM(RTRIM(ProducerCode.TextFre)) As producer,
LTRIM(RTRIM(ProducerCode.Code)) AS producerCode, LTRIM(RTRIM(ProducerCode.Code)) AS producerCode,
LTRIM(RTRIM(GenreCode.TextFre)) As genre, LTRIM(RTRIM(GenreCode.TextFre)) As genre,
LTRIM(RTRIM(GenreCode.Code)) AS genreCode, LTRIM(RTRIM(GenreCode.Code)) AS genreCode,
CASE CASE
WHEN Notices.coverdisplay = 2 THEN 'http://fichiers.bibliothequesonore.ch:8089/netbiblio/images/covers/Cover' + CAST(Notices.NoticeID AS VARCHAR) + '_Original.jpg' WHEN Notices.coverdisplay = 2 THEN 'http://fichiers.bibliothequesonore.ch:8089/netbiblio/images/covers/Cover' + CAST(Notices.NoticeID AS VARCHAR) + '_Original.jpg'
ELSE 'http://ecx.images-amazon.com/images/I/' + Fields.[899a] + '._SL320_.jpg' ELSE 'http://ecx.images-amazon.com/images/I/' + Fields.[899a] + '._SL320_.jpg'
END AS cover, END AS cover,
Fields.[856u] AS link, Fields.[856u] AS link,
Fields.[856z] AS linkTitle, Fields.[856z] AS linkTitle,
LTRIM(RTRIM(Notices.[MediaType1Code])) AS mediaType LTRIM(RTRIM(Notices.[MediaType1Code])) AS mediaType
FROM Notices FROM Notices
INNER JOIN Codes As GenreCode ON Notices.MediaType2Code = GenreCode.Code AND GenreCode.Type = 2 INNER JOIN Codes As GenreCode ON Notices.MediaType2Code = GenreCode.Code AND GenreCode.Type = 2
INNER JOIN Codes AS ProducerCode ON Notices.userdefined3code = ProducerCode.Code AND ProducerCode.Type=6 INNER JOIN Codes AS ProducerCode ON Notices.userdefined3code = ProducerCode.Code AND ProducerCode.Type=6
LEFT OUTER JOIN ( LEFT OUTER JOIN (
SELECT * SELECT *
FROM ( FROM (
SELECT SELECT
NoticeID, NoticeID,
CASE CASE
WHEN Tag IN ('490', '260', '856', '899') THEN Tag + SubfieldCode WHEN Tag IN ('490', '260', '856', '899') THEN Tag + SubfieldCode
ELSE Tag ELSE Tag
END AS Field, END AS Field,
CASE CASE
WHEN Tag = '020' THEN LTRIM(RTRIM(CAST(AuthorityID AS varchar))) WHEN Tag = '020' THEN LTRIM(RTRIM(CAST(AuthorityID AS varchar)))
ELSE LTRIM(RTRIM(ContentShortPart)) ELSE LTRIM(RTRIM(ContentShortPart))
END AS Data END AS Data
FROM NoticeFields FROM NoticeFields
WHERE WHERE
Tag IN ( Tag IN (
'520', -- summary '520', -- summary
'901', -- Reader '901', -- Reader
'300', -- Duration (field media) '300', -- Duration (field media)
'020' -- ISBN '020' -- ISBN
) )
OR (Tag = '490' AND SubfieldCode = 'a') -- Collection OR (Tag = '490' AND SubfieldCode = 'a') -- Collection
OR (Tag = '260' AND SubfieldCode = 'b') -- Editor OR (Tag = '260' AND SubfieldCode = 'b') -- Editor
OR (Tag = '260' AND SubfieldCode = 'c') -- Edition year OR (Tag = '260' AND SubfieldCode = 'c') -- Edition year
OR (Tag = '856' AND SubfieldCode = 'u') -- Link OR (Tag = '856' AND SubfieldCode = 'u') -- Link
OR (Tag = '856' AND SubfieldCode = 'z') -- Link title OR (Tag = '856' AND SubfieldCode = 'z') -- Link title
OR (Tag = '899' AND SubfieldCode = 'a') -- Cover OR (Tag = '899' AND SubfieldCode = 'a') -- Cover
) AS src ) AS src
PIVOT ( PIVOT (
MIN(Data) MIN(Data)
FOR Field IN ([520], [901], [300], [020], [490a], [260b], [260c], [856u], [856z], [899a]) FOR Field IN ([520], [901], [300], [020], [490a], [260b], [260c], [856u], [856z], [899a])
) AS pvt ) AS pvt
) Fields ON Notices.NoticeID = Fields.NoticeID ) Fields ON Notices.NoticeID = Fields.NoticeID
OUTER APPLY ( OUTER APPLY (
SELECT TOP 1 * SELECT TOP 1 *
FROM Items FROM Items
WHERE Notices.NoticeID = NoticeId WHERE Notices.NoticeID = NoticeId
) AS item1 ) AS item1
LEFT JOIN Authorities AS isbn ON isbn.AuthorityID = Fields.[020] LEFT JOIN Authorities AS isbn ON isbn.AuthorityID = Fields.[020]
WHERE WHERE
LTRIM(RTRIM(Notices.[%s])) IN ('%s') LTRIM(RTRIM(Notices.[%s])) IN ('%s')
AND Notices.[NoticeNr] NOT LIKE '%%~%%' AND Notices.[NoticeNr] NOT LIKE '%%~%%'
;", $column, implode('\', \'', $ids)); ;", $column, implode('\', \'', $ids));
$result = Connection::execute($sql, true); $result = Connection::execute($sql, true);
$books = array(); $books = array();
while($row = $result->next()) { while($row = $result->next()) {
$books[$row['id']] = $raw ? $row : new AudioBook($row); $books[$row['id']] = $raw ? $row : new AudioBook($row);
} }
return $multiple ? $books : reset($books); return $multiple ? $books : reset($books);
} }
/** /**
* Retrieve the list of all readers (volunteers) having read at least 4 books (2 notices per book). * 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 * Returns an associative array containing $lastname and $firstname
*/ */
public static function listOfReaders() public static function listOfReaders()
{ {
$sql = "SELECT $sql = "SELECT
count(*), count(*),
ContentShortPart AS name ContentShortPart AS name
FROM NoticeFields FROM NoticeFields
WHERE Tag=901 WHERE Tag=901
GROUP BY ContentShortPart GROUP BY ContentShortPart
HAVING count(*) > 6 HAVING count(*) > 6
ORDER BY SUBSTRING(ContentShortPart, CHARINDEX(' ', ContentShortPart)+1, 15);"; ORDER BY SUBSTRING(ContentShortPart, CHARINDEX(' ', ContentShortPart)+1, 15);";
$results = Connection::execute($sql); $results = Connection::execute($sql);
return array_map(function($row) { return array_map(function($row) {
$fullname = str_replace("*", "", $row['name']); $fullname = str_replace("*", "", $row['name']);
$parts = explode(" ", $fullname); $parts = explode(" ", $fullname);
$firstname = array_shift($parts); $firstname = array_shift($parts);
$lastname = implode(" ", $parts); $lastname = implode(" ", $parts);
return array( return array(
'lastname' => $lastname, 'lastname' => $lastname,
'firstname' => $firstname); 'firstname' => $firstname);
}, $results->to_array()); }, $results->to_array());
} }
/** /**
* Retrieve the list of all type available in the database. * Retrieve the list of all type available in the database.
* @param boolean $withJeunesse add 'Jeunesse' to the list * @param boolean $withJeunesse add 'Jeunesse' to the list
* @return array * @return array
*/ */
public static function ListOfGenres($withJeunesse = false) public static function ListOfGenres($withJeunesse = false)
{ {
$sql = "SELECT DISTINCT $sql = "SELECT DISTINCT
LTRIM(RTRIM(Codes.Code)) as code, LTRIM(RTRIM(Codes.Code)) as code,
LTRIM(RTRIM(Codes.TextFre)) AS text LTRIM(RTRIM(Codes.TextFre)) AS text
FROM Codes FROM Codes
INNER JOIN Notices ON Codes.Code = Notices.MediaType2Code INNER JOIN Notices ON Codes.Code = Notices.MediaType2Code
WHERE WHERE
Codes.Type = 2 Codes.Type = 2
AND Notices.NoticeNr NOT LIKE '%~%' AND Notices.NoticeNr NOT LIKE '%~%'
AND Notices.NoticeNr NOT LIKE '%V%' AND Notices.NoticeNr NOT LIKE '%V%'
AND Notices.NoticeNr NOT LIKE '%T%' AND Notices.NoticeNr NOT LIKE '%T%'
AND Notices.MediaType1Code = 'CDD';"; AND Notices.MediaType1Code = 'CDD';";
$results = Connection::execute($sql)->to_array(); $results = Connection::execute($sql)->to_array();
if($withJeunesse) { if($withJeunesse) {
array_unshift($results, array('code' => 'J', 'text' => 'Jeunesse')); array_unshift($results, array('code' => 'J', 'text' => 'Jeunesse'));
} }
return $results; return $results;
} }
/** /**
* Retrieve the list of all books currently lended to readers. * Retrieve the list of all books currently lended to readers.
*/ */
public static function inReading() public static function inReading()
{ {
$sql = "SELECT $sql = "SELECT
noticenr, title, author, displayName noticenr, title, author, displayName
FROM notices, items, circulations, useraccounts FROM notices, items, circulations, useraccounts
WHERE WHERE
mediatype1code='N' and NoticeNr not like '%~%' mediatype1code='N' and NoticeNr not like '%~%'
AND items.noticeid = notices.noticeid AND items.noticeid = notices.noticeid
AND items.ItemID=circulations.ItemID AND items.ItemID=circulations.ItemID
AND useraccounts.useraccountid=circulations.useraccountid AND useraccounts.useraccountid=circulations.useraccountid
ORDER BY author, title;"; ORDER BY author, title;";
$results = Connection::execute($sql); $results = Connection::execute($sql);
return array_map(function($row) { return array_map(function($row) {
return array( return array(
"noticenr" => $row['noticenr'], "noticenr" => $row['noticenr'],
"auteur" => $row['author'], "auteur" => $row['author'],
"titre" => $row['title'], "titre" => $row['title'],
"lecteur" => $row['displayName'] "lecteur" => $row['displayName']
); );
}, $results->to_array()); }, $results->to_array());
} }
public function __set($name, $value) public function __set($name, $value)
{ {
if ($name == 'code' && is_string($value)) { if ($name == 'code' && is_string($value)) {
$value = preg_replace('/[~a-zA-Z]/', '', $value); $value = preg_replace('/[~a-zA-Z]/', '', $value);
} }
parent::__set($name, $value); parent::__set($name, $value);
} }
} }

@ -1,187 +1,187 @@
<?php <?php
namespace BSR\Lib\db; namespace BSR\Lib\db;
use BSR\Lib\Configuration; use BSR\Lib\Configuration;
use BSR\Lib\Exception\SqlException; use BSR\Lib\Exception\SqlException;
class Connection class Connection
{ {
// Internal variable to hold the connection // Internal variable to hold the connection
private static $db; private static $db;
final private function __construct() {} final private function __construct() {}
/** /**
* @param $query * @param $query
* @param bool $throw_error * @param bool $throw_error
* @return OdbcResultSet|resource|string * @return OdbcResultSet|resource|string
* @throws SqlException * @throws SqlException
*/ */
public static function execute($query, $throw_error = false) public static function execute($query, $throw_error = false)
{ {
$result = odbc_exec(self::get(), utf8_decode($query)); $result = odbc_exec(self::get(), utf8_decode($query));
$result = new OdbcResultSet($result); $result = new OdbcResultSet($result);
if ($result->is_error()) { if ($result->is_error()) {
if($throw_error) { if($throw_error) {
throw new SqlException($result->get_error(), $query); throw new SqlException($result->get_error(), $query);
} }
return $result->get_error(); return $result->get_error();
} }
return $result; return $result;
} }
public static function get() public static function get()
{ {
if (is_null(self::$db)) { if (is_null(self::$db)) {
$dsn = sprintf( $dsn = sprintf(
"Driver={%s};Server=%s,%s;Database=%s;", "Driver={%s};Server=%s,%s;Database=%s;",
Configuration::get('db.driver'), Configuration::get('db.driver'),
Configuration::get('db.server'), Configuration::get('db.server'),
Configuration::get('db.port'), Configuration::get('db.port'),
Configuration::get('db.name') Configuration::get('db.name')
); );
self::$db = odbc_pconnect($dsn, Configuration::get('db.username'), Configuration::get('db.password')); self::$db = odbc_pconnect($dsn, Configuration::get('db.username'), Configuration::get('db.password'));
if (self::$db === false) { if (self::$db === false) {
throw new SqlException("Unable to connect to the server."); throw new SqlException("Unable to connect to the server.");
} }
} }
// Return the connection // Return the connection
return self::$db; return self::$db;
} }
final private function __clone() {} final private function __clone() {}
} }
class OdbcResultSet implements \Iterator, \ArrayAccess class OdbcResultSet implements \Iterator, \ArrayAccess
{ {
public $length; public $length;
private $results; private $results;
private $error; private $error;
private $num_fields; private $num_fields;
private $cursor_index; private $cursor_index;
public function __construct($odbc_result) public function __construct($odbc_result)
{ {
if ($odbc_result === false) { if ($odbc_result === false) {
$this->error = odbc_errormsg(Connection::get()); $this->error = odbc_errormsg(Connection::get());
} else { } else {
try { try {
$this->results = array(); $this->results = array();
$this->num_fields = odbc_num_fields($odbc_result); $this->num_fields = odbc_num_fields($odbc_result);
if ($this->num_fields > 0) { if ($this->num_fields > 0) {
while ($row = odbc_fetch_row($odbc_result)) { while ($row = odbc_fetch_row($odbc_result)) {
$data = array(); $data = array();
for ($i = 1; $i <= $this->num_fields; ++$i) { for ($i = 1; $i <= $this->num_fields; ++$i) {
$data[odbc_field_name($odbc_result, $i)] = utf8_encode(odbc_result($odbc_result, $i)); $data[odbc_field_name($odbc_result, $i)] = utf8_encode(odbc_result($odbc_result, $i));
} }
$this->results[] = $data; $this->results[] = $data;
} }
}; };
} catch (\Exception $e) { } catch (\Exception $e) {
print($e->getMessage()); print($e->getMessage());
} }
$this->cursor_index = 0; $this->cursor_index = 0;
$this->length = count($this->results); $this->length = count($this->results);
odbc_free_result($odbc_result); odbc_free_result($odbc_result);
} }
} }
public function is_error() public function is_error()
{ {
return ($this->error ? true : false); return ($this->error ? true : false);
} }
public function get_error() public function get_error()
{ {
return $this->error; return $this->error;
} }
public function get_row() public function get_row()
{ {
return $this->current(); return $this->current();
} }
public function to_array() public function to_array()
{ {
return $this->results; return $this->results;
} }
// ArrayAccess // ArrayAccess
/** /**
* @param int $offset * @param int $offset
* @return bool * @return bool
*/ */
public function offsetExists($offset) public function offsetExists($offset)
{ {
return !$this->error && $this->cursor_index < $this->length && $this->cursor_index >= 0; return !$this->error && $this->cursor_index < $this->length && $this->cursor_index >= 0;
} }
/** /**
* @param int $offset * @param int $offset
* @return bool|array * @return bool|array
*/ */
public function offsetGet($offset) public function offsetGet($offset)
{ {
return $this->offsetExists($offset) ? $this->results[$offset] : false; return $this->offsetExists($offset) ? $this->results[$offset] : false;
} }
public function offsetSet($offset, $value) public function offsetSet($offset, $value)
{ {
if($this->offsetExists($offset)) { if($this->offsetExists($offset)) {
$this->results[$offset] = $value; $this->results[$offset] = $value;
} }
} }
public function offsetUnset($offset) public function offsetUnset($offset)
{ {
throw new \RuntimeException("This makes no sense at all."); throw new \RuntimeException("This makes no sense at all.");
} }
// Iterator // Iterator
/** /**
* @return bool|array * @return bool|array
*/ */
public function current() public function current()
{ {
return $this->offsetGet($this->cursor_index); return $this->offsetGet($this->cursor_index);
} }
/** /**
* @return int * @return int
*/ */
public function key() public function key()
{ {
return $this->cursor_index; return $this->cursor_index;
} }
/** /**
* @return array|bool * @return array|bool
*/ */
public function next() public function next()
{ {
$current = $this->current(); $current = $this->current();
++$this->cursor_index; ++$this->cursor_index;
return $current; return $current;
} }
public function rewind() public function rewind()
{ {
$this->cursor_index = 0; $this->cursor_index = 0;
} }
/** /**
* @return bool * @return bool
*/ */
public function valid() public function valid()
{ {
return $this->offsetExists($this->cursor_index); return $this->offsetExists($this->cursor_index);
} }
} }

@ -1,126 +1,126 @@
<?php <?php
namespace BSR\Lib\db; namespace BSR\Lib\db;
use BSR\Lib\Exception\InvalidAttributeException; use BSR\Lib\Exception\InvalidAttributeException;
/** /**
* Base class for mapping objects. inherit you database filled objects from here. * Base class for mapping objects. inherit you database filled objects from here.
* *
* @property int $id * @property int $id
*/ */
abstract class DbMapping abstract class DbMapping
{ {
protected $attributes; protected $attributes;
protected $attributeNames = ''; protected $attributeNames = '';
protected $privateAttributeNames = ''; protected $privateAttributeNames = '';
/** /**
* @param array $attributes * @param array $attributes
*/ */
public function __construct(array $attributes) public function __construct(array $attributes)
{ {
$this->setAttributes($attributes); $this->setAttributes($attributes);
} }
/** /**
* Define a bunch of attribute given by an associative array * Define a bunch of attribute given by an associative array
* @param array $attributes * @param array $attributes
*/ */
public function setAttributes(array $attributes) public function setAttributes(array $attributes)
{ {
$this->assertAttributes($attributes); $this->assertAttributes($attributes);
foreach ($attributes as $key => $value) { foreach ($attributes as $key => $value) {
$this->__set($key, $value); $this->__set($key, $value);
} }
} }
/** /**
* Ensure that all keys from attributes are authorized * Ensure that all keys from attributes are authorized
* @param array $attributes * @param array $attributes
*/ */
private function assertAttributes(array $attributes) private function assertAttributes(array $attributes)
{ {
foreach ($attributes as $key => $value) { foreach ($attributes as $key => $value) {
$this->assertAttribute($key); $this->assertAttribute($key);
} }
} }
/** /**
* Ensure that name attribute is authorized * Ensure that name attribute is authorized
* If public_only is false, check agains PRIVATE_ATTRIBUTES_NAME too. * If public_only is false, check agains PRIVATE_ATTRIBUTES_NAME too.
* Those one cannot be accessed via setAttributes and other batch methods. * Those one cannot be accessed via setAttributes and other batch methods.
* @param string $name * @param string $name
* @param bool $public_only * @param bool $public_only
* @throws InvalidAttributeException if the attribute is not a valid one * @throws InvalidAttributeException if the attribute is not a valid one
*/ */
private function assertAttribute($name, $public_only = TRUE) private function assertAttribute($name, $public_only = TRUE)
{ {
if (strpos($this->attributeNames, $name) === false && ($public_only || strpos($this->privateAttributeNames, $name) === false)) { if (strpos($this->attributeNames, $name) === false && ($public_only || strpos($this->privateAttributeNames, $name) === false)) {
throw(new InvalidAttributeException("The attribute $name is invalid")); throw(new InvalidAttributeException("The attribute $name is invalid"));
} }
} }
/** /**
* Get a user attribute or the linked whishes * Get a user attribute or the linked whishes
* @param string $name * @param string $name
* @return mixed * @return mixed
*/ */
public function __get($name) public function __get($name)
{ {
$sql_safe = FALSE; $sql_safe = FALSE;
if (strpos($name, 'sql_') === 0) { if (strpos($name, 'sql_') === 0) {
$name = substr($name, 4); $name = substr($name, 4);
$sql_safe = TRUE; $sql_safe = TRUE;
} }
$this->assertAttribute($name, false); $this->assertAttribute($name, false);
if (isset($this->attributes[$name])) { if (isset($this->attributes[$name])) {
$value = $this->attributes[$name]; $value = $this->attributes[$name];
if ($sql_safe) { if ($sql_safe) {
$value = str_replace("'", "''", $value); $value = str_replace("'", "''", $value);
} }
return $value; return $value;
} else { } else {
return NULL; return NULL;
} }
} }
public function to_array() { public function to_array() {
return $this->attributes; return $this->attributes;
} }
/** /**
* Set a user attribute * Set a user attribute
* @param string $name * @param string $name
* @param mixed $value * @param mixed $value
*/ */
public function __set($name, $value) public function __set($name, $value)
{ {
$this->assertAttribute($name, false); $this->assertAttribute($name, false);
$this->attributes[$name] = $value; $this->attributes[$name] = $value;
} }
/** /**
* Function to retrieve data from an id. * Function to retrieve data from an id.
* @param int $id * @param int $id
* @return DbMapping * @return DbMapping
*/ */
public static function find($id) { public static function find($id) {
throw new \RuntimeException("This method must be implemented in child classes."); throw new \RuntimeException("This method must be implemented in child classes.");
} }
/** /**
* Return all the public attributes in an array; * Return all the public attributes in an array;
*/ */
public function toArray() public function toArray()
{ {
$result = array(); $result = array();
foreach ($this->attributes as $name => $value) { foreach ($this->attributes as $name => $value) {
if (strpos($this->attributeNames, $name) !== false) { if (strpos($this->attributeNames, $name) !== false) {
$result[$name] = $value; $result[$name] = $value;
} }
} }
return $result; return $result;
} }
} }

@ -1,209 +1,209 @@
<?php <?php
namespace BSR\Lib\db; namespace BSR\Lib\db;
use BSR\Lib\Configuration; use BSR\Lib\Configuration;
/** /**
* User is mapped on the Useraccounts table. Contains user information : id, login, firstName, lastName, displayName. * User is mapped on the Useraccounts table. Contains user information : id, login, firstName, lastName, displayName.
* *
* @property int id * @property int id
* @property string $login * @property string $login
* @property string $sql_login * @property string $sql_login
* @property string $password * @property string $password
* @property string $sql_password * @property string $sql_password
* @property string $privatePhone * @property string $privatePhone
* @property string $sql_privatePhone * @property string $sql_privatePhone
* @property string $officePhone * @property string $officePhone
* @property string $sql_officePhone * @property string $sql_officePhone
* @property string $mobilePhone * @property string $mobilePhone
* @property string $sql_mobilePhone * @property string $sql_mobilePhone
* @property string $addressId * @property string $addressId
* @property string $sql_addressId * @property string $sql_addressId
* @property string $displayName * @property string $displayName
* @property string $sql_displayName * @property string $sql_displayName
* @property string $firstName * @property string $firstName
* @property string $sql_firstName * @property string $sql_firstName
* @property string $lastName * @property string $lastName
* @property string $sql_lastName * @property string $sql_lastName
* @property string $mail * @property string $mail
* @property string $sql_mail * @property string $sql_mail
*/ */
class User extends DbMapping class User extends DbMapping
{ {
public static $tableName = 'Useraccounts'; public static $tableName = 'Useraccounts';
public static $idColumn = 'UseraccountID'; public static $idColumn = 'UseraccountID';
protected static $addressTableName = 'Addresses'; protected static $addressTableName = 'Addresses';
protected static $addressIdColumn = 'AddressID'; protected static $addressIdColumn = 'AddressID';
protected static $wishTableName = 'Wishes'; protected static $wishTableName = 'Wishes';
protected $attributeNames = 'id login firstName lastName displayName freeOne mail addressId mobilePhone officePhone privatePhone'; protected $attributeNames = 'id login firstName lastName displayName freeOne mail addressId mobilePhone officePhone privatePhone';
protected $privateAttributeNames = 'password'; protected $privateAttributeNames = 'password';
/** /**
* @param string $login Login for the user * @param string $login Login for the user
* @param string $password Password for the user * @param string $password Password for the user
* @return User|null User object if we were able to authenticate * @return User|null User object if we were able to authenticate
*/ */
public static function authenticate($login, $password) public static function authenticate($login, $password)
{ {
$password = str_replace("'", "''", $password); $password = str_replace("'", "''", $password);
return User::find($login, " UPPER(password) = UPPER('$password') ", false); return User::find($login, " UPPER(password) = UPPER('$password') ", false);
} }
/** /**
* Retrieve a user by its login. Do not represent a valid authentication. * Retrieve a user by its login. Do not represent a valid authentication.
* *
* Cond has to be safe because no check are made inside. * Cond has to be safe because no check are made inside.
* *
* @param string $login login the login name * @param string $login login the login name
* @param string $cond a condition to restrict the choice, optional * @param string $cond a condition to restrict the choice, optional
* @param bool $raiseError * @param bool $raiseError
* @return User the User object or NULL if no user found. * @return User the User object or NULL if no user found.
*/ */
public static function find($login, $cond = '', $raiseError = true) public static function find($login, $cond = '', $raiseError = true)
{ {
$login = str_replace("'", "''", $login); $login = str_replace("'", "''", $login);
if(strlen($cond) > 0) { if(strlen($cond) > 0) {
$cond = " AND $cond"; $cond = " AND $cond";
} }
$sql = sprintf("SELECT TOP 1 $sql = sprintf("SELECT TOP 1
[FirstName] AS firstName, [FirstName] AS firstName,
[LastName] AS lastName, [LastName] AS lastName,
[DisplayName] AS displayName, [DisplayName] AS displayName,
[UserDefined1] AS freeOne, [UserDefined1] AS freeOne,
[ActualAddressID] AS addressId, [ActualAddressID] AS addressId,
[Email] AS mail, [Email] AS mail,
[TelephoneMobile] AS mobilePhone, [TelephoneMobile] AS mobilePhone,
[TelephonePrivate] AS privatePhone, [TelephonePrivate] AS privatePhone,
[Telephone] AS officePhone, [Telephone] AS officePhone,
[%s] AS id, [%s] AS id,
REPLACE(UseraccountNr, ' ', '') AS login REPLACE(UseraccountNr, ' ', '') AS login
FROM [%s] AS u FROM [%s] AS u
LEFT JOIN [%s] AS a ON a.[%s] = u.[ActualAddressID] LEFT JOIN [%s] AS a ON a.[%s] = u.[ActualAddressID]
WHERE REPLACE(UseraccountNr, ' ', '') = '%s' AND disabled = 1 %s;", WHERE REPLACE(UseraccountNr, ' ', '') = '%s' AND disabled = 1 %s;",
self::$idColumn, self::$tableName, self::$addressTableName, self::$addressIdColumn, $login, $cond); self::$idColumn, self::$tableName, self::$addressTableName, self::$addressIdColumn, $login, $cond);
$results = Connection::execute($sql, $raiseError); $results = Connection::execute($sql, $raiseError);
return $results->current() !== false ? new User($results->current()) : null; return $results->current() !== false ? new User($results->current()) : null;
} }
private function _getCirculations($table, $sort = "ItemNr ASC") { private function _getCirculations($table, $sort = "ItemNr ASC") {
$sql = sprintf("SELECT $sql = sprintf("SELECT
NoticeID, NoticeID,
CheckOutDate, CheckOutDate,
ItemNr ItemNr
FROM %s AS c FROM %s AS c
INNER JOIN Items AS i ON i.ItemId = c.ItemId INNER JOIN Items AS i ON i.ItemId = c.ItemId
WHERE WHERE
c.UseraccountId = %s c.UseraccountId = %s
ORDER BY %s", $table, $this->id, $sort); ORDER BY %s", $table, $this->id, $sort);
$result = Connection::execute($sql); $result = Connection::execute($sql);
$circulations = $result->to_array(); $circulations = $result->to_array();
$books = array_map(function($c) { return $c['NoticeID']; }, $circulations); $books = array_map(function($c) { return $c['NoticeID']; }, $circulations);
$books = AudioBook::findBy('NoticeID', $books, true); $books = AudioBook::findBy('NoticeID', $books, true);
foreach($circulations as $c) { foreach($circulations as $c) {
$books[$c['NoticeID']]['date'] = $c['CheckOutDate']; $books[$c['NoticeID']]['date'] = $c['CheckOutDate'];
$books[$c['NoticeID']]['itemNr'] = $c['ItemNr']; $books[$c['NoticeID']]['itemNr'] = $c['ItemNr'];
} }
return $books; return $books;
} }
public function getCirculations() public function getCirculations()
{ {
return $this->_getCirculations('Circulations'); return $this->_getCirculations('Circulations');
} }
public function getOldCirculations() public function getOldCirculations()
{ {
return $this->_getCirculations('OldCirculations', 'CheckOutDate DESC'); return $this->_getCirculations('OldCirculations', 'CheckOutDate DESC');
} }
/** /**
* Add a book to the wish list if it is not already inside. * Add a book to the wish list if it is not already inside.
* @param string $noticeNr * @param string $noticeNr
* @return bool * @return bool
*/ */
public function addWish($noticeNr) public function addWish($noticeNr)
{ {
if ($this->hasWish($noticeNr)) { if ($this->hasWish($noticeNr)) {
return false; return false;
} }
$sql = "UPDATE Counters $sql = "UPDATE Counters
SET WishID = WishID + 1 SET WishID = WishID + 1
OUTPUT INSERTED.WishID;"; OUTPUT INSERTED.WishID;";
$result = Connection::execute($sql, true); $result = Connection::execute($sql, true);
$row = $result->current(); $row = $result->current();
$employee_id = Configuration::get('www_employee_id'); $employee_id = Configuration::get('www_employee_id');
$library_id = Configuration::get('www_library_id'); $library_id = Configuration::get('www_library_id');
$sql = sprintf("INSERT INTO %s $sql = sprintf("INSERT INTO %s
(WishID, NoticeID, %s, CreationDate, EmployeeID, BranchOfficeID, Remark, ModificationDate) (WishID, NoticeID, %s, CreationDate, EmployeeID, BranchOfficeID, Remark, ModificationDate)
SELECT %s , NoticeID, %s, GETDATE() , %s , %s , '' , GETDATE() SELECT %s , NoticeID, %s, GETDATE() , %s , %s , '' , GETDATE()
FROM Notices FROM Notices
WHERE LTRIM(RTRIM(NoticeNr)) = '%s';", WHERE LTRIM(RTRIM(NoticeNr)) = '%s';",
User::$wishTableName, User::$idColumn, $row['WishID'], $this->id, $employee_id, $library_id, $noticeNr); User::$wishTableName, User::$idColumn, $row['WishID'], $this->id, $employee_id, $library_id, $noticeNr);
Connection::execute($sql); Connection::execute($sql);
return true; return true;
} }
/** /**
* Return true if the book is in the wish list * Return true if the book is in the wish list
* @param string $noticeNr * @param string $noticeNr
* @return bool * @return bool
*/ */
private function hasWish($noticeNr) private function hasWish($noticeNr)
{ {
$sql = sprintf("SELECT w.NoticeID $sql = sprintf("SELECT w.NoticeID
FROM Wishes AS w FROM Wishes AS w
INNER JOIN Notices AS n ON n.NoticeID = w.NoticeID INNER JOIN Notices AS n ON n.NoticeID = w.NoticeID
WHERE WHERE
LTRIM(RTRIM(n.NoticeNr)) = '%s' LTRIM(RTRIM(n.NoticeNr)) = '%s'
AND w.UseraccountId = %s;", $noticeNr, $this->id); AND w.UseraccountId = %s;", $noticeNr, $this->id);
$result = Connection::execute($sql); $result = Connection::execute($sql);
return $result->current() !== false; return $result->current() !== false;
} }
/** /**
* Wishes are all the books that this user want to read. * Wishes are all the books that this user want to read.
* @param int $limit * @param int $limit
* @return AudioBook[] * @return AudioBook[]
*/ */
public function getWishes($limit = 50) public function getWishes($limit = 50)
{ {
$sql = sprintf("SELECT TOP $limit $sql = sprintf("SELECT TOP $limit
NoticeID NoticeID
FROM %s FROM %s
WHERE %s = %s WHERE %s = %s
ORDER BY CreationDate DESC" ORDER BY CreationDate DESC"
,User::$wishTableName, User::$idColumn, $this->id); ,User::$wishTableName, User::$idColumn, $this->id);
$result = Connection::execute($sql); $result = Connection::execute($sql);
$ids = array_map(function($r) { return $r['NoticeID']; }, $result->to_array()); $ids = array_map(function($r) { return $r['NoticeID']; }, $result->to_array());
return AudioBook::findBy('NoticeID', $ids, true); return AudioBook::findBy('NoticeID', $ids, true);
} }
/** /**
* Remove a book from the wish list * Remove a book from the wish list
* @param string $noticeNr * @param string $noticeNr
*/ */
public function deleteWish($noticeNr) public function deleteWish($noticeNr)
{ {
$sql = sprintf("DELETE w $sql = sprintf("DELETE w
FROM %s AS w FROM %s AS w
INNER JOIN Notices AS n ON n.NoticeID = w.NoticeID INNER JOIN Notices AS n ON n.NoticeID = w.NoticeID
WHERE WHERE
LTRIM(RTRIM(n.NoticeNr)) = '%s' LTRIM(RTRIM(n.NoticeNr)) = '%s'
AND %s = %s;", User::$wishTableName, $noticeNr, User::$idColumn, $this->id); AND %s = %s;", User::$wishTableName, $noticeNr, User::$idColumn, $this->id);
Connection::execute($sql, true); Connection::execute($sql, true);
} }
} }

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
# README # # README #
This repository contains the code for the WebService used internally at the [BSR](http://bibliothequesonore.ch/) by the Drupal website and both the iOS and Android applications. This repository contains the code for the WebService used internally at the [BSR](http://bibliothequesonore.ch/) by the Drupal website and both the iOS and Android applications.
For more information, please consult the internal documentation : http://192.168.1.250/dokuwiki/doku.php?id=webservice For more information, please consult the internal documentation : http://192.168.1.250/dokuwiki/doku.php?id=webservice

@ -1,20 +1,20 @@
<?php <?php
namespace BSR; namespace BSR;
ini_set('display_errors', 'On'); ini_set('display_errors', 'On');
// register an autoloader to automatically load classes // register an autoloader to automatically load classes
// the namespace for the class must begin with BSR and // the namespace for the class must begin with BSR and
// otherwise respect the PSR-4 standard // otherwise respect the PSR-4 standard
spl_autoload_register(function ($class) { spl_autoload_register(function ($class) {
$class = substr($class, strlen('BSR')); $class = substr($class, strlen('BSR'));
$path = sprintf('%s/%s.php', __DIR__, str_replace('\\', '/', $class)); $path = sprintf('%s/%s.php', __DIR__, str_replace('\\', '/', $class));
if (file_exists($path)) { if (file_exists($path)) {
require $path; require $path;
} }
}); });
$web = new NetBiblio(); $web = new NetBiblio();
$web->Run(); $web->Run();

@ -1,4 +1,4 @@
<?php <?php
// this file is here for compatibility purpose, do not delete // this file is here for compatibility purpose, do not delete
require_once('index.php'); require_once('index.php');
Loading…
Cancel
Save