Commit 87a7048c authored by Alexandre Morin's avatar Alexandre Morin

Merge branch 'release/2.4' into 'master'

Release/2.4 master

See merge request !244
parents 299de1e0 a5ccf42a
......@@ -25,7 +25,7 @@
- `Added` Modification des règles de plusieurs archives sans modifier la date de départ
- `Changed` Gestion des jetons de compte de service
- `Changed` Ajout des routes disponibles pour les privilèges des comptes de service dans la configuration
- `Changed` Ajout des routes disponibles pour les privilèges des comptes de service dans la configuration
- `Fixed` Uniformisation des formats de date
### Métadonnées
......@@ -119,8 +119,7 @@
- `Changed` Modification du format autorisé pour les identifiant d'organisation et de services, autorisant les caractères spéciaux pour permettre l'emploi des barres obliques, points, tirets et soulignements notamment
### Intégrité
- `Added` Stratégies de contrôle d'intégrité périodique définies dans les niveaux de service, avec fréquence de contrôle et taux d'échantillonnage
- `Added` Stratégies de contrôle d'intégrité périodique définies dans les niveaux de service, avec fréquence de contrôle et taux d'échantillonnage
### Sécurité
- `Changed` L'administrateur de la sécurité ne peut désormais plus choisir le mot de passe temporaire. En remplacement, l'intégration d'un client de messagerie électronique permet d'envoyer un courriel à l'utilisateur comportant un mot de passe temporaire généré par l'application
......@@ -34,4 +34,30 @@ Modification de la configuration :
csrfConfig = '{
"cookieName" : "CSRF",
"tokenLength" : 32
}'
\ No newline at end of file
}'
# Migration 2.3 vers 2.4
## Evenement
Ajout de l'évènement recordsManagement/resourceDestruction dans la table "lifeCycle.eventFormat" qui permet la suppression d'une ressource détenue dans une archive.
## Configuration
Rajout des options dateTimeFormat, timestampFormat, timezone dans les paramètres dependency.localisation
```
[dependency.localisation]
@Adapter = Gettext
lang = fr
dateFormat = d-m-Y
dateTimeFormat = "Y-m-d H:i:s \(P\)"
timestampFormat = "Y-m-d H:i:s \(P\)"
timezone = Europe/Paris
```
Ces paramètres permettent de modifier le fuseau horaire et l'affichage des dates à l'écran.
Le paramètre `dateTimeFormat` définit le format d'affichage des valeurs date et heure en suivant le formalisme d'affichage php (se référer à http://php.net/manual/fr/function.date.php )
Le paramètre `timestampFormat` définit le format d'affichage des temps en suivant le formalisme d'affichage php.
Le paramètre `timeZone` définit le fuseau horaire utilisé pour l'affichage en heure locale.
Si ces paramètres sont ignorés, les valeurs par défaut sont chargées par le logiciel, correspondant à un format respectant le standard ISO8601.
\ No newline at end of file
......@@ -213,7 +213,7 @@ abstract class AbstractKernel
* @param string $responseType The contentType definition code used for response
* @param string $responseLanguage The ContentLanguage definition code for response
*/
protected function getResponse($responseType=false, $responseLanguage=false)
protected function getResponse($responseType=null, $responseLanguage=null)
{
switch($this->request->mode) {
case 'http':
......@@ -230,17 +230,9 @@ abstract class AbstractKernel
}
/* Get response type */
if (!$responseType) {
$this->guessResponseType();
} else {
$this->response->setType($responseType);
$mimeType = array_search($responseType, \laabs::getContentTypes());
}
$this->response->setType($responseType);
/* Get response lang */
if (!$responseLanguage) {
$responseLanguage = $this->guessResponseLanguage();
}
$this->response->setLanguage($responseLanguage);
\core\Observer\Dispatcher::notify(LAABS_RESPONSE, $this->response);
......@@ -265,63 +257,18 @@ abstract class AbstractKernel
/**
* Guess the response content type from the request "Accept"
* @return string The ContentType code or "text" as a default value
*/
protected function guessResponseType()
{
$contentTypes = \laabs::getContentTypes();
$requestAccepts = $this->request->accept;
foreach ($requestAccepts as $mimetype => $priority) {
if (isset($contentTypes[$mimetype])) {
$this->response->setType($contentTypes[$mimetype]);
if ($this->response->mode == 'http') {
$this->response->setContentType($mimetype);
}
return;
}
}
}
/**
* Guess the response content language from the request "AcceptLanguage"
* @return string The ContentLanguage code or "en" as a default value
*/
protected function guessResponseLanguage()
{
$contentLanguages = \laabs::getContentLanguages();
$requestAcceptLangs = $this->request->acceptLanguage;
if (!empty($requestAcceptLangs)) {
foreach ($requestAcceptLangs as $locale => $proprity) {
if (isset($contentLanguages[$locale])) {
return $contentLanguages[$locale];
}
}
}
return 'en';
}
/**
* Send response to client
* @access protected
*/
protected function sendResponse()
public function sendResponse()
{
// Buffer will return void if "LAABS_CLEAN_BUFFER" directive set for app
$this->useBuffer();
if (!is_scalar($this->response->body)) {
if (!is_null($this->response->body) && !is_scalar($this->response->body)) {
throw new \core\Exception("Response content can not be displayed");
}
if ($this->response->mode == 'http') {
$this->response->setHeader("X-Laabs-ResponseDelay", \laabs::requestDelay());
}
$this->response->send();
}
......
......@@ -55,12 +55,12 @@ class PresentationKernel
/* Initalize components app/dependecy/bundle */
self::$instance->attachObservers();
\core\Observer\Dispatcher::notify(LAABS_REQUEST, self::$instance->request);
try {
\core\Observer\Dispatcher::notify(LAABS_REQUEST, self::$instance->request);
/* Establish routes (input, action, output) */
self::$instance->setRoutes();
self::$instance->parseRequest();
/* Call Command */
......@@ -395,5 +395,88 @@ class PresentationKernel
}
$this->response->setBody($content);
if (empty($this->response->getContentType())) {
$this->guessResponseType();
}
if (empty($this->response->getHeader('Content-Language'))) {
$this->guessResponseLanguage();
}
$this->response->setHeader('Content-Length', strlen($this->response->body));
}
/**
* Guess the response content type from body or the request "Accept"
* @return string The ContentType code or "text" as a default value
*/
protected function guessResponseType()
{
$finfo = new \finfo();
$mimeType = $finfo->buffer($this->response->body, FILEINFO_MIME_TYPE);
$encoding = $finfo->buffer($this->response->body, FILEINFO_MIME_ENCODING);
$contentType = $mimeType;
if ($mimeType == "text/plain") {
$laabsContentTypes = \laabs::getContentTypes();
$laabsContentType = 'text';
foreach ($this->request->accept as $acceptedMimeType => $priority) {
if (isset($laabsContentTypes[$acceptedMimeType])) {
$laabsContentType = $laabsContentTypes[$acceptedMimeType];
break;
}
}
switch (strtolower($laabsContentType)) {
case 'css':
case 'less':
$contentType = "text/css";
break;
case 'js':
case 'json':
$contentType = "application/javascript";
break;
case 'csv':
$contentType = "text/csv";
break;
case 'html':
$contentType = "text/html";
break;
}
}
$this->response->setContentType($contentType);
}
/**
* Guess the response content language from the request "AcceptLanguage"
* @return string The ContentLanguage code or "en" as a default value
*/
protected function guessResponseLanguage()
{
$contentLanguages = \laabs::getContentLanguages();
$requestAcceptLangs = $this->request->acceptLanguage;
$contentLanguage = 'en';
if (!empty($requestAcceptLangs)) {
foreach ($requestAcceptLangs as $locale => $proprity) {
if (isset($contentLanguages[$locale])) {
$contentLanguage = $contentLanguages[$locale];
break;
}
}
}
$this->response->setHeader('Content-Language', $contentLanguage);
}
}
......@@ -708,7 +708,7 @@ class Bundle
{
$observers = array();
$observerClasses = Extensions::extendedClasses(LAABS_BUNDLE . LAABS_URI_SEPARATOR . $this->name . LAABS_URI_SEPARATOR . LAABS_OBSERVER);
$observerClasses = Extensions::extendedClasses(LAABS_BUNDLE . LAABS_URI_SEPARATOR . $this->name . LAABS_URI_SEPARATOR . LAABS_OBSERVER, true);
foreach ($observerClasses as $observerClass) {
$observerName = \laabs\basename($observerClass);
$observer = new Observer($observerName, $observerClass, $this);
......
......@@ -386,7 +386,8 @@ class Presentation
$observerClasses = Extensions::extendedClasses(
LAABS_PRESENTATION . LAABS_URI_SEPARATOR
. $this->name . LAABS_URI_SEPARATOR
. LAABS_OBSERVER
. LAABS_OBSERVER,
true
);
foreach ($observerClasses as $observerClass) {
$observerName = \laabs\basename($observerClass);
......
......@@ -76,7 +76,9 @@ class Type
parent::__construct($classname);
if ($parentClass = $this->getParentClass()) {
$this->inherit($parentClass->getName());
if ($typeName = \laabs::getClassName($parentClass->getName())) {
$this->inherit($typeName);
}
$this->extension = \laabs::getClassName($parentClass->name);
}
......@@ -165,9 +167,8 @@ class Type
}
protected function inherit($className)
protected function inherit($typeName)
{
$typeName = \laabs::getClassName($className);
$type = \laabs::getClass($typeName);
......
......@@ -26,7 +26,7 @@ abstract class AbstractResponse
public $language;
public $headers;
public $headers = [];
public $body;
......
......@@ -67,49 +67,6 @@ class HttpResponse
return $this->getHeader('Content-Type');
}
public function guessContentType()
{
$finfo = new \finfo();
$type = $finfo->buffer($this->body, FILEINFO_MIME_TYPE);
if (strtok($type, "/") == "text") {
switch(strtolower($this->contentType)) {
case 'css':
case 'less':
$type = "text/css";
break;
case 'js':
$type = "application/javascript";
break;
case 'csv':
$type = "text/csv";
break;
}
}
$encoding = $finfo->buffer($this->body, FILEINFO_MIME_ENCODING);
$contentType = $type . "; charset=" . $encoding;
$this->setContentType($contentType);
}
/**
* Guess the request content type
*/
public function guessResponseType()
{
$contentTypes = \laabs::getContentTypes();
$contentType = $this->headers['Content-Type'];
$mimeType = strtok($contentType, ";");
if (isset($contentTypes[$mimeType])) {
$this->type = $contentTypes[$mimeType];
} else {
throw new \Exception("Could not find a request content handler for the request content type '$contentType'");
}
}
public function setGzip($bool)
{
if ($bool) {
......@@ -147,20 +104,7 @@ class HttpResponse
{
http_response_code($this->code);
if (!headers_sent()) {
$this->setHeader('Content-Length', strlen($this->body));
if (!isset($this->headers['Content-Type'])) {
$this->guessContentType();
}
if (isset($this->contentCount)) {
$this->setHeader('X-Laabs-Content-Count', $this->contentCount);
}
$this->setHeader('X-Laabs-Content-Type', $this->contentType);
$this->setHeader('X-Laabs-Content-Language', $this->language);
if (!headers_sent()) {
foreach ($this->headers as $field => $value) {
header($field . ": " . $value);
}
......
......@@ -37,7 +37,7 @@ class Date
*/
public function jsonSerialize()
{
return (string) $this->format("Y-m-d");
return (string) $this->format();
}
}
\ No newline at end of file
......@@ -57,7 +57,7 @@ class DateTime
*/
public function jsonSerialize()
{
return (string) $this->format("Y-m-d H:i:s");
return (string) $this->format();
}
/**
......
......@@ -105,6 +105,15 @@ class Json
}
/**
* Check value
* @param string $name The name of property
*/
public function __isset($name)
{
return isset($this->value->$name);
}
/**
* Set value
* @param string $name The name of property
* @param mixed $value The value to set
......
......@@ -41,7 +41,7 @@ class Timestamp
*/
public function jsonSerialize()
{
return (string) $this->format("Y-m-d H:i:s.u");
return (string) $this->format();
}
......
......@@ -5,6 +5,8 @@
*/
namespace laabs;
use core\Type\ArrayObject;
/**
* Symbolic links creation for Windows systems
* @param string $target The path to target file/dir
......@@ -597,3 +599,24 @@ function rmdir($dirname, $recurse = true)
return true;
}
/**
* Checks if a value exists in an array
*
* @param $value
* @param $object
*
* @return bool
*/
function in_array($value, $object)
{