archiveAccessTrait.php 47.5 KB
Newer Older
1
2
3
4
5
6
<?php

/*
 *  Copyright (C) 2017 Maarch
 * 
 *  This file is part of bundle XXXX.
Alexis Ragot's avatar
Alexis Ragot committed
7
 *  Bundle recordsManagement is free software: you can redistribute it and/or modify
8
9
10
11
 *  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.
 * 
Alexis Ragot's avatar
Alexis Ragot committed
12
 *  Bundle recordsManagement is distributed in the hope that it will be useful,
13
14
15
16
17
 *  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
Alexis Ragot's avatar
Alexis Ragot committed
18
 *  along with bundle recordsManagement.  If not, see <http://www.gnu.org/licenses/>.
19
20
21
22
23
24
25
26
27
 */

namespace bundle\recordsManagement\Controller;

/**
 * Archive access controller
 *
 * @author Alexis Ragot <alexis.ragot@maarch.org>
 */
28
trait archiveAccessTrait
29
{
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
    /**
     * Search archives by profile / dates / agreement
     * @param string $archiveId
     * @param string $profileReference
     * @param string $status
     * @param string $archiveName
     * @param string $agreementReference
     * @param string $archiveExpired
     * @param string $finalDisposition
     * @param string $originatorOrgRegNumber
     * @param string $originatorOwnerOrgId
     * @param string $originatorArchiveId
     * @param array  $originatingDate
     * @param string $filePlanPosition
     * @param bool   $hasParent
     * @param string $description
     * @param string $text
     * @param bool   $partialRetentionRule
     * @param string $retentionRuleCode
     * @param string $depositStartDate
     * @param string $depositEndDate
     * @param string $originatingStartDate
     * @param string $originatingEndDate
53
     * @param string $archiverArchiveId
54
     * @param string $processingStatus
55
     * @param bool   $checkAccess
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
     *
     * @return recordsManagement/archive[] Array of recordsManagement/archive object
     */
    public function search(
        $archiveId = null,
        $profileReference = null,
        $status = null,
        $archiveName = null,
        $agreementReference = null,
        $archiveExpired = null,
        $finalDisposition = null,
        $originatorOrgRegNumber = null,
        $originatorOwnerOrgId = null,
        $originatorArchiveId = null,
        $originatingDate = null,
        $filePlanPosition = null,
        $hasParent = null,
        $description = null,
        $text = null,
        $partialRetentionRule = null,
        $retentionRuleCode = null,
        $depositStartDate = null,
        $depositEndDate = null,
        $originatingStartDate = null,
80
        $originatingEndDate = null,
81
        $archiverArchiveId = null,
82
83
        $processingStatus = null,
        $checkAccess = true
84
    ) {
85
86
87
        $accountController = \laabs::newController('auth/userAccount');
        $accountController->isAuthorized('user');

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
        $archives = [];

        $archiveArgs = [
            'archiveId' => $archiveId,
            'profileReference' => $profileReference,
            'status' => $status,
            'archiveName' => $archiveName,
            'agreementReference' => $agreementReference,
            'archiveExpired' => $archiveExpired,
            'finalDisposition' => $finalDisposition,
            'originatorOrgRegNumber' => $originatorOrgRegNumber,
            'originatorOwnerOrgId' => $originatorOwnerOrgId,
            'originatorArchiveId' => $originatorArchiveId,
            'originatingDate' => $originatingDate,
            'filePlanPosition' => $filePlanPosition,
            'hasParent' => $hasParent,
            'partialRetentionRule' => $partialRetentionRule,
            'retentionRuleCode' => $retentionRuleCode,
            'depositStartDate' => $depositStartDate,
            'depositEndDate' => $depositEndDate,
            'originatingDate' => [$originatingStartDate, $originatingEndDate], // [0] startDate, [1] endDate
109
110
            'archiverArchiveId' => $archiverArchiveId,
            'processingStatus' => $processingStatus
111
112
        ];

113
114
115
116
        if (!$filePlanPosition) {
            unset($archiveArgs['filePlanPosition']);
        }

117
118
119
120
        $searchClasses = [];
        if (!$profileReference) {
            $searchClasses['recordsManagement/description'] = $this->useDescriptionController('recordsManagement/description');

121
            $descriptionSchemeController = \laabs::newController('recordsManagement/descriptionScheme');
122

123
124
125
126
            foreach ($descriptionSchemeController->index() as $name => $descriptionScheme) {
                if (isset($descriptionScheme->search)) {
                    $searchClasses[$name] = $this->useDescriptionController($descriptionScheme->search);
                }
127
128
129
130
131
132
133
134
135
136
            }
        } else {
            $archivalProfile = $this->archivalProfileController->getByReference($profileReference);
            if ($archivalProfile->descriptionClass != '') {
                $searchClasses[$archivalProfile->descriptionClass] = $this->useDescriptionController($archivalProfile->descriptionClass);
            } else {
                $searchClasses['recordsManagement/description'] = $this->useDescriptionController('recordsManagement/description');
            }
        }
        foreach ($searchClasses as $descriptionClass => $descriptionController) {
137
            $archives = array_merge($archives, $descriptionController->search($description, $text, $archiveArgs, $checkAccess));
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
        }

        return $archives;
    }

    /**
     * Search archives by profile / dates / agreement
     * @param string $archiveId
     * @param string $profileReference
     * @param string $status
     * @param string $archiveName
     * @param string $agreementReference
     * @param string $archiveExpired
     * @param string $finalDisposition
     * @param string $originatorOrgRegNumber
     * @param string $originatorOwnerOrgId
     * @param string $originatorArchiveId
     * @param array  $originatingDate
     * @param string $filePlanPosition
     * @param bool   $hasParent
     * @param string $description
     * @param string $text
     * @param bool   $partialRetentionRule
     * @param string $retentionRuleCode
     * @param string $depositStartDate
     * @param string $depositEndDate
     * @param string $originatingStartDate
     * @param string $originatingEndDate
     *
     * @return recordsManagement/archive[] Array of recordsManagement/archive object
     */
Cyril Vazquez's avatar
Typo    
Cyril Vazquez committed
169
    public function searchRegistry(
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
        $archiveId = null,
        $profileReference = null,
        $status = null,
        $archiveName = null,
        $agreementReference = null,
        $archiveExpired = null,
        $finalDisposition = null,
        $originatorOrgRegNumber = null,
        $originatorOwnerOrgId = null,
        $originatorArchiveId = null,
        $originatingDate = null,
        $filePlanPosition = null,
        $hasParent = null,
        $description = null,
        $text = null,
        $partialRetentionRule = null,
        $retentionRuleCode = null,
        $depositStartDate = null,
        $depositEndDate = null,
        $originatingStartDate = null,
        $originatingEndDate = null
    ) {
192
193
194
        $accountController = \laabs::newController('auth/userAccount');
        $accountController->isAuthorized('user');

195
196
197
198
199
200
        $queryParts = array();
        $queryParams = array();

        $currentDate = \laabs::newDate();
        $currentDateString = $currentDate->format('Y-m-d');

201
        if ($archiveId) {
202
203
204
            $queryParts['archiveId'] = "archiveId = :archiveId";
            $queryParams['archiveId'] = $archiveId;
        } else {
205
            if ($profileReference) {
206
207
                $queryParts['archivalProfileReference'] = "archivalProfileReference = :archivalProfileReference";
                $queryParams['archivalProfileReference'] = $profileReference;
208
            }
209

210
            if ($status) {
211
212
                $queryParts['status'] = "status = :status";
                $queryParams['status'] = $status;
213
214
            }

215
            if ($retentionRuleCode) {
216
217
218
                $queryParts['retentionRuleCode'] = "retentionRuleCode = :retentionRuleCode";
                $queryParams['retentionRuleCode'] = $retentionRuleCode;
            }
219

220
            if ($filePlanPosition) {
221
222
223
                $queryParts['filePlanPosition'] = "filePlanPosition = :filePlanPosition";
                $queryParams['filePlanPosition'] = $filePlanPosition;
            }
224

225
            if ($originatorArchiveId) {
226
227
228
                $queryParts['originatorArchiveId'] = "originatorArchiveId = :originatorArchiveId";
                $queryParams['originatorArchiveId'] = $originatorArchiveId;
            }
229

230
            if ($originatorOrgRegNumber) {
231
232
233
                $queryParts['originatorOrgRegNumber'] = "originatorOrgRegNumber = :originatorOrgRegNumber";
                $queryParams['originatorOrgRegNumber'] = $originatorOrgRegNumber;
            }
234

235
            if ($finalDisposition) {
236
237
238
                $queryParts['finalDisposition'] = "finalDisposition = :finalDisposition";
                $queryParams['finalDisposition'] = $finalDisposition;
            }
239

240
241
242
243
244
245
246
            if ($originatingStartDate && $originatingEndDate) {
                $queryParams['originatingStartDate'] = $originatingStartDate;
                $queryParams['originatingEndDate'] = $originatingEndDate;
                $queryParts['originatingDate'] = "originatingDate >= :originatingStartDate AND originatingDate <= :originatingEndDate";
            } elseif ($originatingStartDate) {
                $queryParams['originatingStartDate'] = $originatingStartDate;
                $queryParts['originatingDate'] = "originatingDate >= :originatingStartDate";
247

248
249
250
251
            } elseif ($originatingEndDate) {
                $queryParams['originatingEndDate'] = $originatingEndDate;
                $queryParts['originatingDate'] = "originatingDate <= :originatingEndDate";
            }
252

253
254
255
256
257
258
259
            if ($depositStartDate && $depositEndDate) {
                $queryParams['depositStartDate'] = $depositStartDate;
                $queryParams['depositEndDate'] = $depositEndDate;
                $queryParts['depositDate'] = "depositDate >= :depositStartDate AND depositDate <= :depositEndDate";
            } elseif ($depositStartDate) {
                $queryParams['depositStartDate'] = $depositStartDate;
                $queryParts['depositDate'] = "depositDate >= :depositStartDate";
260

261
262
263
264
            } elseif ($depositEndDate) {
                $queryParams['depositEndDate'] = $depositEndDate;
                $queryParts['depositDate'] = "depositDate <= :depositEndDate";
            }
265
            if ($archiveExpired) {
266
267
268
                if ($archiveExpired == "true") {
                    $queryParams['disposalDate'] = $currentDateString;
                    $queryParts['disposalDate'] = "disposalDate <= :disposalDate";
269
                } elseif ($archiveExpired == "false") {
270
271
                    $queryParams['disposalDate'] = $currentDateString;
                    $queryParts['disposalDate'] = "disposalDate >= :disposalDate";
272
                }
273
            }
274

275
276
277
278
            if ($partialRetentionRule) {
                $queryParts['partialRetentionRule'] = "(retentionDuration=NULL 
                OR retentionStartDate=NULL 
                OR retentionRuleCode=NULL)";
279
280
            }

281
        }
282

283
284
        $queryParams['descriptionClass'] = 'recordsManagement/log';
        $queryParts['descriptionClass'] = "(descriptionClass != :descriptionClass OR descriptionClass=NULL)";
285

286
        $accessRuleAssert = $this->getAccessRuleAssert($currentDateString);
287

288
289
        if ($accessRuleAssert) {
            $queryParts[] = $accessRuleAssert;
290
291
        }

292
        $queryString = \laabs\implode(' AND ', $queryParts);
Alexandre Morin's avatar
Alexandre Morin committed
293
294
295
296
297
298
299
300
301
        $maxResults = \laabs::configuration('presentation.maarchRM')['maxResults'];
        $archives = $this->sdoFactory->find(
            'recordsManagement/archive',
            $queryString,
            $queryParams,
            false,
            false,
            $maxResults
        );
302

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
        foreach ($archives as $archive) {
            if (!empty($archive->disposalDate) && $archive->disposalDate <= \laabs::newDate()) {
                $archive->disposable = true;
            }
        }

        return $archives;
    }

    /**
     * Get archives list
     * @param string  $originatorOrgRegNumber The organization registration number
     * @param string  $filePlanPosition       The file plan position
     * @param boolean $archiveUnit            List the archive unit
     *
     * @return array recordsManagement/archive
     */
    public function index($originatorOrgRegNumber, $filePlanPosition = null, $archiveUnit = false)
    {
        $queryParts = array();
        $queryParams = array();

325
326
327
        $currentDate = \laabs::newDate();
        $currentDateString = $currentDate->format('Y-m-d');

328
329
330
        $queryParts['status'] = "status != :status";
        $queryParams['status'] = 'disposed';

331
        if ($originatorOrgRegNumber) {
332
333
334
335
            $queryParts['originatorOrgRegNumber'] = "originatorOrgRegNumber = :originatorOrgRegNumber";
            $queryParams['originatorOrgRegNumber'] = $originatorOrgRegNumber;
        }

336
        if ($filePlanPosition) {
337
338
            $queryParts['filePlanPosition'] = "filePlanPosition = :filePlanPosition";
            $queryParams['filePlanPosition'] = $filePlanPosition;
Prosper De Laure's avatar
Prosper De Laure committed
339
        } else {
340
            $queryParts['filePlanPosition'] = "filePlanPosition = null";
341
342
        }

343
        if ($archiveUnit == false) {
344
345
346
            $queryParts['parentArchiveId'] = "parentArchiveId = null";
        }

347
        if ($archiveUnit == true) {
348
349
350
351
352
353
354
355
            $queryParts['parentArchiveId'] = "parentArchiveId != null";
        }

        $accessRuleAssert = $this->getAccessRuleAssert($currentDateString);

        if ($accessRuleAssert) {
            $queryParts[] = $accessRuleAssert;
        }
356
        
357
        $queryString = \laabs\implode(' AND ', $queryParts);
Alexandre Morin's avatar
Alexandre Morin committed
358
359
360
361
362
363
364
365
366
        $maxResults = \laabs::configuration('presentation.maarchRM')['maxResults'];
        $archives = $this->sdoFactory->find(
            'recordsManagement/archive',
            $queryString,
            $queryParams,
            false,
            false,
            $maxResults
        );
367
368
369
370
371
372
373
374
375
376

        foreach ($archives as $archive) {
            if (!empty($archive->disposalDate) && $archive->disposalDate <= \laabs::newDate()) {
                $archive->disposable = true;
            }
        }

        return $archives;
    }

377
378
    /**
     * Get archive metadata
379
     * @param string $archiveId   The archive identifier
380
     * 
381
382
     * @return recordsManagement/archive The archive metadata
     */
383
    public function getMetadata($archiveId, $checkAccess = true)
384
    {
385
        if (is_scalar($archiveId)) {
Shiva SIVANESARAJAH's avatar
Shiva SIVANESARAJAH committed
386
            $archive = $this->sdoFactory->read('recordsManagement/archive', $archiveId);
387
        } else {
Shiva SIVANESARAJAH's avatar
Shiva SIVANESARAJAH committed
388
389
390
            $archive = $archiveId;
        }
        $this->getAccessRule($archive);
391

392
393
        if ($checkAccess) {
            $this->checkRights($archive);
394
395
        }

396
        $descriptionController = $this->useDescriptionController($archive->descriptionClass);
397
398
399
400
401
402
403
404

        $archive->descriptionObject = $descriptionController->read($archive->archiveId);

        return $archive;
    }

    /**
     * Get the related information of an archive
405
406
407
     * @param string $archiveId   The identifier of the archive or the archive itself
     * @param bool   $checkAccess Check access for originator or archiver. if false, caller MUST control access before or after
     * 
408
     * @return recordsManagement/archive
409
     */
410
    public function getRelatedInformation($archiveId, $checkAccess = true)
411
412
    {
        if (is_scalar($archiveId)) {
413
            $archive = $this->sdoFactory->read('recordsManagement/archive', $archiveId);
414
        } else {
415
            $archive = $archiveId;
416
        }
417
418
419
420

        if ($checkAccess) {
            $this->checkRights($archive);
        }
421

422
        $archive->lifeCycleEvent = $this->getArchiveLifeCycleEvent($archive->archiveId);
423
        $archive->relationships = $this->getArchiveRelationship($archive->archiveId);
424

425
        return $archive;
426
427
428
429
    }

    /**
     * Get the children of an archive as an index
430
     * @param string $archiveId         The identifier of the archive or the archive itself
431
     * @param bool   $loadResourcesInfo Load the resources info
432
     * @param bool   $loadBinary        Load the resources binary
433
434
435
     *
     * @return array recordsManagement/archive
     */
436
    public function listChildrenArchive($archiveId, $loadResourcesInfo = false, $loadBinary = false, $checkAccess = true)
437
438
    {
        if (is_scalar($archiveId)) {
439
            $archive = $this->sdoFactory->read('recordsManagement/archive', $archiveId);
440
        } else {
441
            $archive = $archiveId;
442
        }
443
444
445
        
        $archive->digitalResources = $this->getDigitalResources($archive->archiveId, $checkAccess);
        
Prosper De Laure's avatar
Prosper De Laure committed
446
447
448
449
450
        if ($archive->digitalResources) {
            if ($loadBinary) {
                foreach ($archive->digitalResources as $i => $digitalResource) {
                    $archive->digitalResources[$i] = $this->digitalResourceController->retrieve($digitalResource->resId);
                }
Prosper De Laure's avatar
Prosper De Laure committed
451

Prosper De Laure's avatar
Prosper De Laure committed
452
453
454
455
            } elseif ($loadResourcesInfo) {
                foreach ($archive->digitalResources as $i => $digitalResource) {
                    $archive->digitalResources[$i] = $this->digitalResourceController->info($digitalResource->resId);
                }
456
457
            }
        }
458
        
459
        $archive->contents = $this->sdoFactory->find(
460
461
462
            "recordsManagement/archive",
            "parentArchiveId='".(string) $archive->archiveId."'"
        );
463
        
464
465
        if ($archive->contents) {
            foreach ($archive->contents as $child) {
466
                $this->listChildrenArchive($child, $loadResourcesInfo, $loadBinary, $checkAccess);
Prosper De Laure's avatar
Prosper De Laure committed
467
            }
468
        }
469
        
470
471
472
        return $archive;
    }

473
474
475
476
477
478
479
480
481
482
    public function listChildrenArchiveId($archiveId)
    {
        $archiveIds[] = $archiveId;

        $archives = $this->sdoFactory->find(
            "recordsManagement/archive",
            "parentArchiveId='".(string) $archiveId."'"
        );

        foreach ($archives as $archive) {
483
484
            $archiveId = (string)$archive->archiveId;
            $archiveIds = array_merge($archiveIds, $this->listChildrenArchiveId($archiveId));
485
486
487
488
489
        }

        return $archiveIds;
    }

490
491
    /**
     * Retrieve an archive resource contents
492
493
494
     * @param string $archiveId   The archive identifier
     * @param bool   $checkAccess Check access for originator or archiver. if false, caller MUST control access before or after
     * 
495
496
     * @return digitalResource/digitalResource[] Array of digitalResource/digitalResource object
     */
497
    public function getDigitalResources($archiveId, $checkAccess = true)
498
    {
499
500
        $archive = $this->sdoFactory->read('recordsManagement/archive', $archiveId);

501
502
503
        if ($checkAccess) {
            $this->checkRights($archive);
        }
504

505
        return $this->digitalResourceController->getResourcesByArchiveId($archiveId);
506
507
508
509
    }

    /**
     * Retrieve an archive resource contents
510
     *
511
512
513
514
     * @param string $archiveId   The archive identifier
     * @param string $resId       The resource identifier
     * @param bool   $checkAccess Check access for originator or archiver. if false, caller MUST control access before or after
     * 
515
516
     * @return digitalResource/digitalResource Archive resource contents
     */
517
    public function consultation($archiveId, $resId, $checkAccess = true, $isCommunication = false)
518
    {
519
520
521
        $accountController = \laabs::newController('auth/userAccount');
        $accountController->isAuthorized('user');

522
        $archive = $this->sdoFactory->read('recordsManagement/archive', $archiveId);
523

524
        if ($checkAccess) {
525
            $this->checkRights($archive, $isCommunication);
526
        }
527

528
529
530
531
532
533
534
535
536
537
538
539
540
541
        try {
            $digitalResource = $this->digitalResourceController->retrieve($resId);

            $resourceIntegrity = true;
            foreach ($digitalResource->address as $address) {
                if (!$address->integrityCheckResult) {
                    $resourceIntegrity = false;
                }
            }

            if (!$resourceIntegrity) {
                $this->logIntegrityCheck($archive, "Invalid resource", $digitalResource, false);
            }

542
            if (($checkAccess && !$this->accessVerification($archive)) || $digitalResource->archiveId != $archiveId) {
543
544
545
546
547
548
549
550
551
552
553
554
555
                throw \laabs::newException('recordsManagement/accessDeniedException', "Permission denied");
            }

            $this->logConsultation($archive, $digitalResource);

        } catch (\Exception $e) {
            $this->logConsultation($archive, $digitalResource, false);

            throw $e;
        }

        $binaryDataObject = \laabs::newInstance("recordsManagement/BinaryDataObject");
        $binaryDataObject->attachment = new \stdClass();
556

557
        $binaryDataObject->attachment->data = $digitalResource->getHandler();
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
        $binaryDataObject->attachment->uri = "";
        $binaryDataObject->attachment->filename = $digitalResource->fileName;

        if (!empty($digitalResource->fileExtension)) {
            $digitalResource->fileName = $digitalResource->fileName . $digitalResource->fileExtension;
        }

        $binaryDataObject->format = $digitalResource->puid;
        $binaryDataObject->mimetype = $digitalResource->mimetype;
        $binaryDataObject->size = $digitalResource->size;

        $binaryDataObject->messageDigest = new \stdClass();
        $binaryDataObject->messageDigest->value = $digitalResource->hash;
        $binaryDataObject->messageDigest->algorithm = $digitalResource->hashAlgorithm;

        return $binaryDataObject;
    }

    /**
     * Retrieve an archive by its id
578
     *
579
580
581
     * @param string $archiveId   The archive identifier
     * @param bool   $withBinary  Retrieve contents or only metadata
     * @param bool   $checkAccess Check access for originator or archiver. if false, caller MUST control access before or after
582
     * @throws
583
     * @return recordsManagement/archive object
584
     */
585
    public function retrieve($archiveId, $withBinary = false, $checkAccess = true, $isCommunication = false)
586
    {
587
588
589
        $accountController = \laabs::newController('auth/userAccount');
        $accountController->isAuthorized('user');

590
        if (is_scalar($archiveId)) {
Shiva SIVANESARAJAH's avatar
Shiva SIVANESARAJAH committed
591
            $archive = $this->sdoFactory->read('recordsManagement/archive', $archiveId);
592
        } else {
Shiva SIVANESARAJAH's avatar
Shiva SIVANESARAJAH committed
593
594
            $archive = $archiveId;
        }
595
        
596
597
598
599
        if ($isCommunication) {
            $this->checkRights($archive, $isCommunication);
            $checkAccess = false;
        } else {
600
601
            $this->checkRights($archive);
        }
602
        
603
        $this->getMetadata($archive, $checkAccess);
Shiva SIVANESARAJAH's avatar
Shiva SIVANESARAJAH committed
604
        $archive->originatorOrg = $this->organizationController->getOrgByRegNumber($archive->originatorOrgRegNumber);
605
        
Shiva SIVANESARAJAH's avatar
Shiva SIVANESARAJAH committed
606
607
608
609
610
611
        if (!empty($archive->archiverOrgRegNumber)) {
            $archive->archiverOrg = $this->organizationController->getOrgByRegNumber($archive->archiverOrgRegNumber);
        }
        if (!empty($archive->depositorOrgRegNumber)) {
            $archive->depositorOrg = $this->organizationController->getOrgByRegNumber($archive->depositorOrgRegNumber);
        }
612
613
        $this->getRelatedInformation($archive, $checkAccess);
        $this->listChildrenArchive($archive, true, $withBinary, $checkAccess);
614
        
Alexandre Morin's avatar
Alexandre Morin committed
615
616
        $this->getParentArchive($archive);

617
618
        if (!empty($archive->contents)) {
            foreach ($archive->contents as $child) {
619
                $this->retrieve($child, $withBinary, $checkAccess, $isCommunication);
Shiva SIVANESARAJAH's avatar
Shiva SIVANESARAJAH committed
620
621
622
            }
        }

623
624
625
626
        $archive->communicability = true;
        if ($checkAccess) {
            $archive->communicability = $this->accessVerification($archive);
        }
Shiva SIVANESARAJAH's avatar
Shiva SIVANESARAJAH committed
627

Cyril Vazquez's avatar
Cyril Vazquez committed
628
        $archive->messages = $this->getMessageByArchiveid($archive->archiveId);
Shiva SIVANESARAJAH's avatar
Shiva SIVANESARAJAH committed
629

630
631
        return $archive;
    }
632

633
634
635
636
637
638
639
640
641
642
    /**
     * Get an archive life cycle event
     * @param string $archiveId The archive identifier
     *
     * @return array lifeCycle/event
     */
    public function getArchiveLifeCycleEvent($archiveId)
    {
        return $this->lifeCycleJournalController->getObjectEvents($archiveId, 'recordsManagement/archive');
    }
Alexis Ragot's avatar
Alexis Ragot committed
643

644
645
646
647
    /**
     * Get an archive relationship
     * @param string $archiveId The archive identifier
     *
648
     * @return array recordsManagement/archiveRelationship
649
650
651
652
     */
    public function getArchiveRelationship($archiveId)
    {
        $res = [];
653
        $res['childrenRelationships'] = $this->archiveRelationshipController->getByArchiveId($archiveId);
654
655
        foreach ($res['childrenRelationships'] as $childRelationship) {
            $relatedArchiveInfo = $this->read($childRelationship->relatedArchiveId);
Alexandre Morin's avatar
Alexandre Morin committed
656
            $childRelationship->relatedArchiveName = $relatedArchiveInfo->archiveName;
657
        }
658
        $res['parentRelationships'] = $this->archiveRelationshipController->getByRelatedArchiveId($archiveId);
659
660
        foreach ($res['parentRelationships'] as $parentRelationship) {
            $relatedArchiveInfo = $this->read($parentRelationship->archiveId);
Alexandre Morin's avatar
Alexandre Morin committed
661
            $parentRelationship->relatedArchiveName = $relatedArchiveInfo->archiveName;
662
        }
Alexis Ragot's avatar
Alexis Ragot committed
663

664
        return $res;
665
666
667
668
    }

    /**
     * Validate archive access
669
     *
670
     * @param string $archiveId The archive identifier
671
672
     *
     * @return boolean The result of the authorization access
673
674
675
     */
    public function accessVerification($archiveId)
    {
Shiva SIVANESARAJAH's avatar
Shiva SIVANESARAJAH committed
676
        $archive = $this->sdoFactory->read('recordsManagement/archive', $archiveId);
677
678
679
680
681
682
683
684

        $comDateAccess = $this->accessComDateVerification($archive);

        $currentService = \laabs::getToken("ORGANIZATION");
        if (!$currentService) {
            return false;
        }

685
686
687
688
        $userServiceOrgRegNumbers = array_merge(
            array($currentService->registrationNumber),
            $this->userPositionController->readDescandantService((string) $currentService->orgId)
        );
689
690
691
692
693
694
695
696
697

        foreach ($userServiceOrgRegNumbers as $userServiceOrgRegNumber) {
            $userService = $this->organizationController->getOrgByRegNumber($userServiceOrgRegNumber);

            // User orgUnit is owner
            if (isset($userService->orgRoleCodes) && (strpos((string) $userService->orgRoleCodes, 'owner') !== false)) {
                return true;
            }

Alexis Ragot's avatar
Alexis Ragot committed
698
            // Archiver or Originator
699
700
            if ($userServiceOrgRegNumber == (string) $archive->archiverOrgRegNumber
                || $userServiceOrgRegNumber == (string) $archive->originatorOrgRegNumber) {
701
702
703
704
705
706
707
708
                return true;
            }

            // If date is in the past, public communication is allowed
            if ($userService->ownerOrgId == $archive->originatorOwnerOrgId && $comDateAccess) {
                return true;
            }
        }
709
710
    }

711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
    /**
     * Verification of the communication date for access
     *
     * @param recordsManagement/archive $archive The archive to verify
     *
     * @return boolean The access right
     */
    private function accessComDateVerification($archive)
    {
        $access = true;

        if ($archive->accessRuleComDate) {
            $communicationDelay = $archive->accessRuleComDate->diff(\laabs::newTimestamp());
            $access = $communicationDelay->invert == 0 ? true : false;
        }

        return $access;
    }
Cyril Vazquez's avatar
Cyril Vazquez committed
729
730
731
732

    /**
     * Get archive assert
     * @param array $args
733
     * @param array $queryParams
734
     * @param bool  $checkAccess
735
     *
736
     * @return string Query
Cyril Vazquez's avatar
Cyril Vazquez committed
737
     */
738
    public function getArchiveAssert($args, &$queryParams, $checkAccess = true)
Cyril Vazquez's avatar
Cyril Vazquez committed
739
740
741
742
743
    {
        // Args on archive
        $currentDate = \laabs::newDate();
        $currentDateString = $currentDate->format('Y-m-d');

744
        $queryParts = [];
Cyril Vazquez's avatar
Cyril Vazquez committed
745
746
747
748
        if (!empty($args['archiveName'])) {
            $queryParts[] = "archiveName='*".$args['archiveName']."*'";
        }
        if (!empty($args['profileReference'])) {
Dylan's avatar
Dylan committed
749
750
            $queryParts['archivalProfileReference'] = "archivalProfileReference = :archivalProfileReference";
            $queryParams['archivalProfileReference']=$args['profileReference'];
Cyril Vazquez's avatar
Cyril Vazquez committed
751
752
        }
        if (!empty($args['agreementReference'])) {
Dylan's avatar
Dylan committed
753
754
            $queryParts['archivalAgreementReference'] = "archivalAgreementReference=:archivalAgreementReference";
            $queryParts['archivalAgreementReference'] = $args['agreementReference'];
Cyril Vazquez's avatar
Cyril Vazquez committed
755
756
        }
        if (!empty($args['archiveId'])) {
Dylan's avatar
Dylan committed
757
758
            $queryParts['archiveId'] = "archiveId=:archiveId";
            $queryParams['archiveId'] = $args['archiveId'];
Cyril Vazquez's avatar
Cyril Vazquez committed
759
760
        }
        if (!empty($args['status'])) {
Dylan's avatar
Dylan committed
761
762
            $queryParts['status'] = "status=:status";
            $queryParams['status'] = $args['status'];
Cyril Vazquez's avatar
Cyril Vazquez committed
763
        }
764
        if (!empty($args['retentionRuleCode'])) {
Dylan's avatar
Dylan committed
765
766
            $queryParts[] = "retentionRuleCode=:retentionRuleCode";
            $queryParams['retentionRuleCode'] = $args['retentionRuleCode'];
767
        }
768
        if (!empty($args['archiveExpired']) && $args['archiveExpired'] == "true") {
Dylan's avatar
Dylan committed
769
770
            $queryParts['disposalDate'] = "disposalDate<= :disposalDate";
            $queryParams['disposalDate'] = $currentDateString;
Cyril Vazquez's avatar
Cyril Vazquez committed
771
        }
772
        if (!empty($args['archiveExpired']) && $args['archiveExpired'] == "false") {
Dylan's avatar
Dylan committed
773
774
            $queryParts['disposalDate'] = "disposalDate>= :disposalDate";
            $queryParams['disposalDate'] = $currentDateString;
Cyril Vazquez's avatar
Cyril Vazquez committed
775
        }
776
        if (!empty($args['partialRetentionRule']) && $args['partialRetentionRule'] == "true") {
777
778
779
780
781
            $queryParts['partialRetentionRule'] = "(
            retentionDuration=NULL 
            OR retentionStartDate=NULL 
            OR retentionRuleCode=NULL
            )";
782
        }
Cyril Vazquez's avatar
Cyril Vazquez committed
783
        if (!empty($args['finalDisposition'])) {
Dylan's avatar
Dylan committed
784
785
            $queryParts['finalDisposition'] = "finalDisposition= :finalDisposition";
            $queryParams['finalDisposition'] =$args['finalDisposition'];
Cyril Vazquez's avatar
Cyril Vazquez committed
786
787
        }
        if (!empty($args['originatorOrgRegNumber'])) {
Dylan's avatar
Dylan committed
788
789
            $queryParts[] = "originatorOrgRegNumber= :originatorOrgRegNumber";
            $queryParams['originatorOrgRegNumber'] = $args['originatorOrgRegNumber'];
Cyril Vazquez's avatar
Cyril Vazquez committed
790
        }
791
        if (!empty($args['originatorArchiveId'])) {
Dylan's avatar
Dylan committed
792
793
            $queryParts['originatorArchiveId'] = "originatorArchiveId= :originatorArchiveId";
            $queryParams['originatorArchiveId'] = $args['originatorArchiveId'];
794
        }
795
796
797
798
        if (!empty($args['archiverArchiveId'])) {
            $queryParts['archiverArchiveId'] = "archiverArchiveId= :archiverArchiveId";
            $queryParams['archiverArchiveId'] = $args['archiverArchiveId'];
        }
799
        if (!empty($args['originatingDate'])) {
800
801
802
803
804
805
806
807
808
            if (!empty($args['originatingDate'][0]) && is_string($args['originatingDate'][0])) {
                $args['originatingDate'][0] = \laabs::newDate($args['originatingDate'][0]);
            }
            if (!empty($args['originatingDate'][1]) && is_string($args['originatingDate'][1])) {
                $args['originatingDate'][1] = \laabs::newDate($args['originatingDate'][1]);
            }

            if (!empty($args['originatingDate'][0])) { // originatingStartDate
                $args['originatingDate'][0] = $args['originatingDate'][0]->format('Y-m-d');
809
810
                $queryParts['originatingDate0'] = "originatingDate>= :originatingDate0";
                $queryParams['originatingDate0'] =$args['originatingDate'][0];
811
            }
Dylan's avatar
Dylan committed
812
            if (!empty($args['originatingDate'][1])) { // originatingEndDate;
813
                $args['originatingDate'][1] = $args['originatingDate'][1]->format('Y-m-d');
814
815
                $queryParts['originatingDate1'] = "originatingDate<= :originatingDate1";
                $queryParams['originatingDate1'] = $args['originatingDate'][1];
816
817
            }
        }
818
819
820
821
822
823
824
825
826
827
828

        if (!empty($args['depositStartDate']) && is_string($args['depositStartDate'])) {
            $args['depositStartDate'] = \laabs::newDate($args['depositStartDate']);
        }
        if (!empty($args['depositEndDate']) && is_string($args['depositEndDate'])) {
            $args['depositEndDate'] = \laabs::newDate($args['depositEndDate']);
        }

        if (!empty($args['depositStartDate']) && !empty($args['depositEndDate'])) {
            $args['depositStartDate'] = $args['depositStartDate']->format('Y-m-d').'T00:00:00';
            $args['depositEndDate'] = $args['depositEndDate']->format('Y-m-d').'T23:59:59';
Dylan's avatar
Dylan committed
829
830
831
            $queryParts['depositDate'] = "depositDate <= :depositEndDate AND depositDate >= :depositStartDate";
            $queryParams['depositEndDate'] = $args['depositEndDate'];
            $queryParams['depositStartDate'] = $args['depositStartDate'];
832
833
        } elseif (!empty($args['depositStartDate'])) {
            $args['depositStartDate'] = $args['depositStartDate']->format('Y-m-d').'T00:00:00';
Dylan's avatar
Dylan committed
834
835
            $queryParts['depositDate'] = "depositDate >= :depositStartDate";
            $queryParams['depositStartDate'] = $args['depositStartDate'];
836
837
        } elseif (!empty($args['depositEndDate'])) {
            $args['depositEndDate'] = $args['depositEndDate']->format('Y-m-d').'T23:59:59';
Dylan's avatar
Dylan committed
838
839
            $queryParts['depositDate'] = "depositDate <= :depositEndDate";
            $queryParams['depositEndDate'] = $args['depositEndDate'];
840
841
        }

Cyril Vazquez's avatar
Cyril Vazquez committed
842
        if (!empty($args['depositorOrgRegNumber'])) {
Dylan's avatar
Dylan committed
843
844
            $queryParts['depositorOrgRegNumber'] = "depositorOrgRegNumber= :depositorOrgRegNumber";
            $queryParams['depositorOrgRegNumber'] = $args['depositorOrgRegNumber'];
Cyril Vazquez's avatar
Cyril Vazquez committed
845
        }
846
        if (!empty($args['filePlanPosition'])) {
847
848
            $foldersId = $this->getDescendantFolder($args['filePlanPosition']);
            $queryParts['filePlanPosition'] = "filePlanPosition=['".implode("', '", $foldersId)."']";
Cyril Vazquez's avatar
Cyril Vazquez committed
849
        }
850
851
852
853
854
855
        if (isset($args['hasParent'])) {
            if ($args['hasParent'] == true) {
                $queryParts['parentArchiveId'] = "parentArchiveId!=null";
            } elseif ($args['hasParent']  === false) {
                $queryParts['hasParent'] = "parentArchiveId=null";
            }
Cyril Vazquez's avatar
Cyril Vazquez committed
856
        }
857
858
859
860
861
862
        
        if (isset($args['processingStatus'])) {
            if ($args['processingStatus'] === true) {
                $queryParts['processingStatus'] = "processingStatus!=null";
            } elseif ($args['processingStatus'] === false) {
                $queryParts['processingStatus'] = "processingStatus=null";
863
            } elseif (is_string($args['processingStatus'])) {
864
865
866
                $queryParts['processingStatus'] = "processingStatus= :processingStatus";
                $queryParams['processingStatus'] = $args['processingStatus'];
            }
Cyril Vazquez's avatar
Cyril Vazquez committed
867
868
        }

869
870
        if ($checkAccess) {
            $accessRuleAssert = $this->getAccessRuleAssert($currentDateString);
Dylan's avatar
Dylan committed
871

872
873
874
            if ($accessRuleAssert) {
                $queryParts[] = $accessRuleAssert;
            }
875
        }
Cyril Vazquez's avatar
Cyril Vazquez committed
876
877
878
879
880
881
882

        return implode(' and ', $queryParts);
    }

    /**
     * Get the query assert for access rule
     * @param string $currentDateString the date
883
     *
884
     * @return string Query
Cyril Vazquez's avatar
Cyril Vazquez committed
885
886
887
888
889
890
891
892
     */
    public function getAccessRuleAssert($currentDateString)
    {
        $currentService = \laabs::getToken("ORGANIZATION");
        if (!$currentService) {
            return "true=false";
        }

893
894
895
896
        $userServiceOrgRegNumbers = array_merge(
            array($currentService->registrationNumber),
            $this->userPositionController->readDescandantService((string) $currentService->orgId)
        );
Cyril Vazquez's avatar
Cyril Vazquez committed
897
898
899
900
901
902
903
904
905
906

        foreach ($userServiceOrgRegNumbers as $userServiceOrgRegNumber) {
            $userService = $this->organizationController->getOrgByRegNumber($userServiceOrgRegNumber);
            if (isset($userService->orgRoleCodes) && $userService->orgRoleCodes->contains('owner')) {
                return;
            }
        }

        $queryParts['originator'] = "originatorOrgRegNumber=['".implode("', '", $userServiceOrgRegNumbers)."']";
        $queryParts['archiver'] = "archiverOrgRegNumber=['".implode("', '", $userServiceOrgRegNumbers)."']";
Alexandre Morin's avatar
Alexandre Morin committed
907
        $queryParts['user'] = "(userOrgRegNumbers = '".$currentService->registrationNumber."' OR userOrgRegNumbers = '".$currentService->registrationNumber." *' OR userOrgRegNumbers = '* ".$currentService->registrationNumber." *' OR userOrgRegNumbers = '* ".$currentService->registrationNumber."')";
Cyril Vazquez's avatar
Cyril Vazquez committed
908
909
        //$queryParts['depositor'] = "depositorOrgRegNumber=['". implode("', '", $userServiceOrgRegNumbers) ."']";

910
911
        $queryParts['accessRule'] = "(originatorOwnerOrgId = '".$currentService->ownerOrgId
            ."' AND (accessRuleComDate <= '$currentDateString'))";
Cyril Vazquez's avatar
Cyril Vazquez committed
912
913
914

        return "(".implode(" OR ", $queryParts).")";
    }
915
916

    /**
917
918
     * Get the parent archive
     * @param recordsManagement/archive $archive The archive
919
     *
920
     * @return recordsManagement/archive Parent archive
921
     */
922
    protected function getParentArchive($archive)
923
    {
924
925
        if (isset($archive->parentArchiveId)) {
            $archive->parentArchive = $this->sdoFactory->read("recordsManagement/archive", $archive->parentArchiveId);
926
927
        }

928
        return $archive;
929
930
931
    }

    /**
932
933
934
     * Change the status of an archive
     * @param mixed  $archiveIds Identifiers of the archives to update
     * @param string $status     New status to set
935
     * @param bool   $isUnFreeze
936
937
     * @param bool   $withChildren
     * @param bool   $withParents
938
     *
Cyril Vazquez's avatar
Cyril Vazquez committed
939
     * @return array Archives ids separate by successfully updated archives ['success'] and not updated archives ['error']
940
     */
941
942
943
944
945
946
947
    public function setStatus(
        $archiveIds,
        $status,
        $isUnFreeze = false,
        $withChildren = true,
        $withParents = false
    ) {
948
        $statusList = [];
949

950
        if ($isUnFreeze) {
951
952
953
954
            $statusList['preserved'] = array('frozen', 'disposable', 'error', 'restituable', 'transferable');
        } else {
            $statusList['preserved'] = array('disposable', 'error', 'restituable', 'transferable');
        }
Cyril Vazquez's avatar
Cyril Vazquez committed
955
        $statusList['restituable'] = array('preserved');
956
        $statusList['restituted'] = array('restituable');
Cyril Vazquez's avatar
Cyril Vazquez committed
957
958
959
960
961
962
        $statusList['transfered'] = array('transferable');
        $statusList['frozen'] = array('preserved', 'restituable', 'disposable', 'transferable');
        $statusList['disposable'] = array('preserved');
        $statusList['transferable'] = array('preserved');
        $statusList['disposed'] = array('disposable', 'restituted');
        $statusList['error'] = array('preserved', 'restituable', 'restituted', 'frozen', 'disposable', 'disposed');
963

964
        if (!is_array($archiveIds)) {
Alexandre Morin's avatar
Alexandre Morin committed
965
            $archiveIds = array((string) $archiveIds);
966
967
968
969
        } else {
            foreach ($archiveIds as $key => $archiveId) {
                $archiveIds[$key] = (string) $archiveId;
            }
970
        }
971

972
        $res = array('success' => array(), 'error' => array());
973

974
975
        if (!isset($statusList[$status])) {
            $res['error'] = $archiveIds;
976

977
978
            return $res;
        }
979

980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
        if ($withChildren || $withParents) {
            $archiveIdsWithChildren = $archiveIdsWithParents = [];

            $archiveIds = array_flip($archiveIds);
            foreach ($archiveIds as $archiveId => $key) {
                if ($withChildren) {
                    $archiveIdsWithChildren = array_merge(
                        $archiveIdsWithChildren,
                        $this->getChildrenArchives($archiveId)
                    );
                }

                if ($withParents) {
                    $archiveIdsWithParents = array_merge(
                        $archiveIdsWithParents,
                        $this->getParentsArchives($archiveId)
                    );

                }
            }