Commit 5ee7848e authored by Cyril Vazquez's avatar Cyril Vazquez
Browse files

FEAT #5745 Fix various errors on archival profile load and use

parent 07219abe
ALTER TABLE "recordsManagement"."archivalProfile" ADD COLUMN "acceptArchiveWithoutProfile" boolean default true;
ALTER TABLE "recordsManagement"."archivalProfile" ADD COLUMN "acceptAnyProfile" boolean default false;
CREATE TABLE "recordsManagement"."archivalProfileRelationship"
CREATE TABLE "recordsManagement"."archivalProfileContents"
(
"parentProfileId" text NOT NULL,
"containedProfileId" text NOT NULL,
PRIMARY KEY ("parentProfileId", "containedProfileId"),
FOREIGN KEY ("parentProfileId")
REFERENCES "recordsManagement"."archivalProfile" ("archivalProfileId") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
REFERENCES "recordsManagement"."archivalProfile" ("archivalProfileId") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
FOREIGN KEY ("containedProfileId")
REFERENCES "recordsManagement"."archivalProfile" ("archivalProfileId") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
REFERENCES "recordsManagement"."archivalProfile" ("archivalProfileId") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
\ No newline at end of file
......@@ -101,9 +101,10 @@ class organization
/**
* Set positions for the organization tree
* @param object $roots The organization tree roots
* @param array $organizationList The list of organization sorted by parent organization
*
* @param object $roots The organization tree roots
* @param array $organizationList The list of organization sorted by parent organization
*
* @return array
*/
protected function buildTree($roots, $organizationList)
{
......@@ -393,7 +394,7 @@ class organization
}
foreach ($descendants as $descendantOrg) {
if((string) $descendantOrg->orgId == $organization->orgId) {
if ((string) $descendantOrg->orgId == $organization->orgId) {
throw new \bunble\organization\Exception\orgMoveException("Organization can't be moved to a descendent organization");
}
......@@ -473,8 +474,8 @@ class organization
/**
* Add a service position to an organization
* @param string $serviceAccountId The service account identifier
* @param string $orgId The organization identifier
* @param string $serviceAccountId The service account identifier
*
* @return boolean The result of the operation
*/
......@@ -578,7 +579,7 @@ class organization
$contacts = array();
foreach ($orgContacts as $orgContact) {
try{
try {
$contact = \laabs::callService('contact/contact/read_contactId_', $orgContact->contactId);
$contacts[] = (object) array_merge((array) $contact, (array) $orgContact);
} catch (\Exception $e) {
......@@ -690,7 +691,7 @@ class organization
$i = false;
while ($i == false) {
if ($org->parentOrgId) {
$org = $this->sdoFactory->find('organization/organization',"orgId = '$org->parentOrgId'")[0];
$org = $this->sdoFactory->find('organization/organization', "orgId = '$org->parentOrgId'")[0];
$parentsOrg[] = $org;
} else {
$i = true;
......@@ -712,7 +713,7 @@ class organization
$this->sdoFactory->deleteChildren("organization/archivalProfileAccess", array("orgId" => $orgId), 'organization/organization');
foreach ($archivalProfileAccess as $access) {
$access = (object)$access;
$access = (object) $access;
$access->orgId = $orgId;
$this->sdoFactory->create($access, "organization/archivalProfileAccess");
......@@ -743,7 +744,7 @@ class organization
$orgUnitArchivalProfiles[] ='*';
continue;
}
$orgUnitArchivalProfiles[] = $archivalProfileController->getByReference($archivalProfileAccess->archivalProfileReference, $whitRelatedProfile=true);
$orgUnitArchivalProfiles[] = $archivalProfileController->getByReference($archivalProfileAccess->archivalProfileReference, $withRelatedProfile = true);
}
return $orgUnitArchivalProfiles;
......
......@@ -95,7 +95,7 @@ class archivalProfile
/**
* get an archival profile by reference
* @param string $archivalProfileReference The archival profile reference
* @param bool $withRelatedProfiles Bring back the contents profiles
* @param bool $withRelatedProfiles Bring back the contents profiles
*
* @return recordsManagement/archivalProfile The profile object
*/
......@@ -103,6 +103,8 @@ class archivalProfile
{
$archivalProfile = $this->sdoFactory->read('recordsManagement/archivalProfile', array('reference' => $archivalProfileReference));
$this->readDetail($archivalProfile);
if ($withRelatedProfiles) {
$archivalProfile->containedProfiles = $this->getContentsProfiles($archivalProfile->archivalProfileId);
}
......@@ -187,17 +189,19 @@ class archivalProfile
public function getContentsProfiles($archivalProfileId, $recursively = false)
{
$containedProfiles = [];
$relationships = $this->sdoFactory->find('recordsManagement/archivalProfileRelationship', "parentProfileId ='$archivalProfileId'");
$contents = $this->sdoFactory->find('recordsManagement/archivalProfileContents', "parentProfileId ='$archivalProfileId'");
if (count($relationships)) {
foreach ($relationships as $relationship) {
$profile = $this->sdoFactory->read('recordsManagement/archivalProfile', $relationship->containedProfileId);
if (count($contents)) {
foreach ($contents as $content) {
$containedProfile = $this->sdoFactory->read('recordsManagement/archivalProfile', $content->containedProfileId);
$this->readDetail($containedProfile);
if ($recursively) {
$profile->containedProfiles = $this->getContentsProfiles($relationship->containedProfileId, $recursively);
$containedProfile->containedProfiles = $this->getContentsProfiles($content->containedProfileId, $recursively);
}
$containedProfiles[] = $profile;
$containedProfiles[] = $containedProfile;
}
}
......@@ -294,9 +298,7 @@ class archivalProfile
$this->sdoFactory->create($archivalProfile, 'recordsManagement/archivalProfile');
$this->createDetail($archivalProfile);
// Contents profiles
$this->updateContainedProfiles($archivalProfile, $archivalProfile->containedProfiles);
// Life cycle journal
$eventItems = array('archivalProfileReference' => $archivalProfile->reference);
$this->lifeCycleJournalController->logEvent('recordsManagement/profileCreation', 'recordsManagement/archivalProfile', $archivalProfile->archivalProfileId, $eventItems);
......@@ -331,15 +333,13 @@ class archivalProfile
}
try {
$archivalProfile = \laabs::cast($archivalProfile, 'recordsManagement/archivalProfile');
//$archivalProfile = \laabs::cast($archivalProfile, 'recordsManagement/archivalProfile');
$this->deleteDetail($archivalProfile);
$this->createDetail($archivalProfile);
// archival profile
$this->sdoFactory->update($archivalProfile, "recordsManagement/archivalProfile");
// Contents profiles
$this->updateContainedProfiles($archivalProfile, $archivalProfile->containedProfiles);
// Life cycle journal
$eventItems = array('archivalProfileReference' => $archivalProfile->reference);
......@@ -359,84 +359,7 @@ class archivalProfile
return true;
}
/**
* Cpdate an archival content profile
* @param object $archivalProfile The parent profile
* @param array $containedProfiles The content profiles identifiers
*
* @return boolean The request of the request
*/
protected function updateContainedProfiles($archivalProfile, $containedProfiles)
{
if ($archivalProfile->acceptAnyProfile) {
$containedProfiles = [];
}
if (count($containedProfiles)) {
// Validation
foreach ($containedProfiles as $profileId) {
try {
$profile = $this->sdoFactory->read("recordsManagement/archivalProfile", $profileId);
} catch (\Exception $e) {
throw new \core\Exception\NotFoundException("$profileId can't be found.");
}
if (!$this->validateContainedProfile($archivalProfile->archivalProfileId, $profileId)) {
throw new \core\Exception\ForbiddenException("$profile->reference can't be content in this archival profile.");
}
}
}
$oldcontainedProfiles = $this->sdoFactory->find("recordsManagement/archivalProfileRelationship", "parentProfileId = '$archivalProfile->archivalProfileId'");
if (count($oldcontainedProfiles)) {
$this->sdoFactory->deleteCollection($oldcontainedProfiles, "recordsManagement/archivalProfileRelationship");
}
if (count($containedProfiles)) {
$archivalProfileRelationships = [];
foreach ($containedProfiles as $containedProfileId) {
$archivalProfileRelationship = \laabs::newInstance('recordsManagement/archivalProfileRelationship');
$archivalProfileRelationship->parentProfileId = $archivalProfile->archivalProfileId;
$archivalProfileRelationship->containedProfileId = $containedProfileId;
$archivalProfileRelationships[] = $archivalProfileRelationship;
}
$this->sdoFactory->createCollection($archivalProfileRelationships, "recordsManagement/archivalProfileRelationship");
}
return true;
}
/**
* Validate an archival profile contents profiles
* @param string $archivalProfileId The parent profile identifier
* @param string $containedProfileId The contents profiles identifiers to validate
*
* @return boolean The request of the request
*/
protected function validateContainedProfile($parentProfileId, $containedProfileId)
{
if ($parentProfileId == $containedProfileId) {
return false;
}
$relationships = $this->sdoFactory->find("recordsManagement/archivalProfileRelationship", "parentProfileId = '$containedProfileId'");
if (count($relationships)) {
foreach ($relationships as $relationship) {
if (!$this->validateContainedProfile($parentProfileId, $relationship->containedProfileId)) {
return false;
}
}
}
return true;
}
/**
* delete an archival profile
* @param string $archivalProfileId The identifier of the archival profile
......@@ -447,13 +370,6 @@ class archivalProfile
{
$archivalProfile = $this->sdoFactory->read('recordsManagement/archivalProfile', $archivalProfileId);
// containedProfiles
$archivalProfileRelationships = $this->sdoFactory->find("recordsManagement/archivalProfileRelationship", "parentProfileId='$archivalProfileId' or containedProfileId='$archivalProfileId'");
if (count($archivalProfileRelationships)) {
$this->sdoFactory->deleteCollection($archivalProfileRelationships, "recordsManagement/archivalProfileRelationship");
}
//$this->sdoFactory->deleteChildren("recordsManagement/archivalProfileRelationship", $archivalProfile);
$this->deleteDetail($archivalProfile);
$this->sdoFactory->delete($archivalProfile);
......@@ -492,18 +408,35 @@ class archivalProfile
$this->sdoFactory->create($description, 'recordsManagement/archiveDescription');
}
}
// Contents profiles
if (!empty($archivalProfile->containedProfiles)) {
foreach ($archivalProfile->containedProfiles as $containedProfileId) {
try {
$profile = $this->sdoFactory->read("recordsManagement/archivalProfile", $containedProfileId);
} catch (\Exception $e) {
throw new \core\Exception\NotFoundException("$containedProfileId can't be found.");
}
$archivalProfileContents = \laabs::newInstance('recordsManagement/archivalProfileContents');
$archivalProfileContents->parentProfileId = $archivalProfile->archivalProfileId;
$archivalProfileContents->containedProfileId = $containedProfileId;
$this->sdoFactory->create($archivalProfileContents, 'recordsManagement/archivalProfileContents');
}
}
}
protected function deleteDetail($archivalProfile)
{
$this->sdoFactory->deleteChildren('recordsManagement/archiveDescription', $archivalProfile);
/*$documentProfiles = $this->sdoFactory->readChildren('recordsManagement/documentProfile', $archivalProfile);
foreach ($documentProfiles as $documentProfile) {
$this->sdoFactory->deleteChildren('recordsManagement/documentDescription', $documentProfile);
}
$this->sdoFactory->deleteChildren('recordsManagement/archiveDescription', $archivalProfile, 'recordsManagement/archivalProfile');
$this->sdoFactory->deleteChildren('recordsManagement/documentProfile', $archivalProfile);*/
$this->sdoFactory->deleteChildren('recordsManagement/archivalProfileContents', $archivalProfile, 'recordsManagement/archivalProfile');
}
}
......@@ -70,7 +70,6 @@ trait archiveEntryTrait
*
* @param recordsManagement/archive $archive The archive to receive
* @param bool $zipContainer The archive is a zip container
*
*/
public function receive($archive, $zipContainer = false)
{
......@@ -112,6 +111,8 @@ trait archiveEntryTrait
* Process a zipContainer
*
* @param recordsManagement/archive $archive The archive
*
* @return recordsManagement/archive
*/
public function processZipContainer($archive)
{
......@@ -180,7 +181,7 @@ trait archiveEntryTrait
/**
* Extract the archive unit
*
* @param string $filename The filename
* @param string $filename The filename
*
* @return recordsManagement/archive The extracted archive from directory
*/
......@@ -278,6 +279,7 @@ trait archiveEntryTrait
*/
public function validateCompliance($archive)
{
$this->validateFileplan($archive);
$this->validateArchiveDescriptionObject($archive);
$this->validateManagementMetadata($archive);
$this->validateAttachments($archive);
......@@ -407,16 +409,13 @@ trait archiveEntryTrait
if (is_string($archive->retentionStartDate)) {
$qname = \laabs\explode("/", $archive->retentionStartDate);
if ($qname[0] == "description") {
if (isset($archive->descriptionObject->{$qname[1]})) {
$archive->retentionStartDate = \laabs::newDate($archive->descriptionObject->{$qname[1]});
}
if ($qname[0] == "description" && isset($archive->descriptionObject->{$qname[1]})) {
$archive->retentionStartDate = \laabs::newDate($archive->descriptionObject->{$qname[1]});
} else {
// todo
$archive->retentionStartDate = null;
}
}
}
$archive->disposalDate = null;
if (!empty($archive->retentionStartDate) && !empty($archive->retentionDuration) && $archive->retentionDuration->y < 999) {
$archive->disposalDate = $archive->retentionStartDate->shift($archive->retentionDuration);
......@@ -436,10 +435,13 @@ trait archiveEntryTrait
$archive->serviceLevelReference = $this->currentServiceLevel->reference;
}
/**
* Convert resources of archive
*
* @param recordsManagement/archive $archive The archive to convert
*
* @return void
*/
public function convertArchive($archive)
{
......@@ -501,15 +503,9 @@ trait archiveEntryTrait
try {
if (!$archive->parentArchiveId && !$this->organizationController->checkProfileInOrgAccess($archive->archivalProfileReference, $archive->originatorOrgRegNumber)) {
throw new \core\Exception\ForbiddenException("Invalid archive profile");
}
$archive->status = 'preserved';
$archive->depositDate = \laabs::newTimestamp();
$this->validateArchivalProfile($archive);
$this->openContainers($archive, $path);
$this->sdoFactory->create($archive, 'recordsManagement/archive');
......@@ -660,30 +656,37 @@ trait archiveEntryTrait
*
* @param \bundle\recordsManagement\Controller\recordsManagement/archive $archive
*/
protected function validateArchivalProfile($archive)
protected function validateFileplan($archive)
{
if ($archive->parentArchiveId == "") {
if (!$this->organizationController->checkProfileInOrgAccess($archive->archivalProfileReference, $archive->originatorOrgRegNumber)) {
throw new \core\Exception\BadRequestException("Invalid archive profile");
}
return;
}
$parentArchiveId = $this->sdoFactory->read('recordsManagement/archive', $archive->parentArchiveId);
$this->useArchivalProfile($parentArchiveId->archivalProfileReference);
if ($archive->archivalProfileReference == "" && $this->currentArchivalProfile->acceptArchiveWithoutProfile) {
return;
$parentArchive = $this->sdoFactory->read('recordsManagement/archive', $archive->parentArchiveId);
if (!empty($parentArchive->archivalProfileReference)) {
if (!isset($this->archivalProfiles[$parentArchive->archivalProfileReference])) {
$parentArchivalProfile = $this->archivalProfileController->getByReference($parentArchive->archivalProfileReference);
$this->archivalProfiles[$parentArchive->archivalProfileReference] = $parentArchivalProfile;
} else {
$parentArchivalProfile = $this->archivalProfiles[$parentArchive->archivalProfileReference];
}
}
if ($archive->archivalProfileReference != "" && $this->currentArchivalProfile->acceptAnyProfile) {
return;
if ($archive->archivalProfileReference == "" && !$parentArchivalProfile->acceptArchiveWithoutProfile) {
throw new \core\Exception\BadRequestException("Invalid archive profile");
}
foreach ($this->currentArchivalProfile->containedProfiles as $profile) {
if ($profile->reference == $archive->archivalProfileReference) {
foreach ($parentArchivalProfile->containedProfiles as $containedProfile) {
if ($containedProfile->reference == $archive->archivalProfileReference) {
return;
}
}
}
throw new \core\Exception\ForbiddenException("Invalid archive profile");
throw new \core\Exception\BadRequestException("Invalid archive profile");
}
......
......@@ -105,13 +105,6 @@ class archivalProfile
*/
public $acceptArchiveWithoutProfile;
/**
* The archive accepts sub archive of any profile
*
* @var boolean
*/
public $acceptAnyProfile;
/**
* The list of profile description
*
......
......@@ -102,18 +102,11 @@ class archivalProfile
/**
* The archive accepts sub archive without profile
*
*
* @var boolean
*/
public $acceptArchiveWithoutProfile;
/**
* The archive accepts sub archive of any profile
*
* @var boolean
*/
public $acceptAnyProfile;
/**
* The list of profile description
*
......@@ -124,7 +117,7 @@ class archivalProfile
/**
* The list of child archival profiles
*
* @var array
* @var recordsManagement/archivalProfileContents[]
*/
public $containedProfiles = array();
......
<?php
/*
* Copyright (C) 2015 Maarch
*
* This file is part of bundle recordsManagement.
*
* Bundle recordsManagement is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Bundle recordsManagement is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with bundle recordsManagement. If not, see <http://www.gnu.org/licenses/>.
*/
namespace bundle\recordsManagement\Model;
/**
* Class model that represents a relationship between 2 archives
*
* @package RecordsManagement
* @author Prosper DE LAURE (Maarch) <prosper.delaure@maarch.org>
*
* @pkey [parentProfileId, containedProfileId]
* @fkey [parentProfileId] recordsManagement/archivalProfile [archivalProfileId]
* @fkey [containedProfileId] recordsManagement/archivalProfile [archivalProfileId]
*/
class archivalProfileContents
{
/**
* The parent profile identifier
*
* @var string
* @notempty
*/
public $parentProfileId;
/**
* The related profile identifier
*
* @var string
* @notempty
*/
public $containedProfileId;
} // END class archive
......@@ -56,9 +56,7 @@ CREATE TABLE "recordsManagement"."archivalProfile"
"description" text,
"accessRuleCode" text,
"acceptUserIndex" boolean default false,
"acceptMultipleDocuments" boolean default false,
"acceptArchiveWithoutProfile" boolean default true,
"acceptAnyProfile" boolean default false,
PRIMARY KEY ("archivalProfileId"),
UNIQUE ("reference"),
FOREIGN KEY ("accessRuleCode")
......@@ -72,15 +70,15 @@ WITH (
OIDS=FALSE
);
CREATE TABLE "recordsManagement"."archivalProfileRelationship"
CREATE TABLE "recordsManagement"."archivalProfileContents"
(
"parentProfileId" text NOT NULL,
"containedProfileId" text NOT NULL,
PRIMARY KEY ("parentProfileId", "contentProfileId"),
PRIMARY KEY ("parentProfileId", "containedProfileId"),
FOREIGN KEY ("parentProfileId")
REFERENCES "recordsManagement"."archivalProfile" ("archivalProfileId") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
FOREIGN KEY ("contentProfileId")
FOREIGN KEY ("containedProfileId")
REFERENCES "recordsManagement"."archivalProfile" ("archivalProfileId") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
......
......@@ -41,6 +41,8 @@ class Exception
$this->view = $view;
$this->json = $json;
$this->translator = $translator;
$this->translator->setCatalog('exceptions/messages');
}
/**
......@@ -64,9 +66,8 @@ class Exception
if (method_exists($exception, "setMessage")) {
$exception->setMessage($this->translator->getText($exception->getFormat()));
$this->json->message = $exception->getMessage();
} else if($message = $exception->getMessage()) {
} else if ($message = $exception->getMessage()) {
$this->json->message = $message;
} else {
$this->json->message = $this->translator->getText(
"An error occured during the process of your request. Please contact the administrator of the application.");
......
......@@ -34,7 +34,7 @@ class welcome
/**
* Constuctor of welcomePage html serializer
* @param \dependency\html\Document $view The view
* @param \dependency\json\JsonObject $json
* @param \dependency\json\JsonObject $json Json utility
*/
public function __construct(\dependency\html\Document $view, \dependency\json\JsonObject $json)
{
......@@ -95,6 +95,7 @@ class welcome
}
$archivalProfileController->readDetail($archivalProfile);
$archivalProfile->searchFields = [];
foreach ($archivalProfile->archiveDescription as $archiveDescription) {
switch ($archiveDescription->descriptionField->type) {
......@@ -111,7 +112,6 @@ class welcome