Newer
Older
<?php
/**
* Copyright Maarch since 2008 under licence GPLv3.
* See LICENCE.txt file at the root folder for more details.
* This file is part of Maarch software.
*
*/
/**
* @brief Resource Controller
* @author dev@maarch.org
*/
namespace Document\controllers;
use Attachment\controllers\AttachmentController;
use setasign\Fpdi\Tcpdf\Fpdi;
use Document\models\DocumentModel;
use Slim\Http\Request;
use Slim\Http\Response;
use SrcCore\models\DatabaseModel;
use SrcCore\models\ValidatorModel;
use Status\models\StatusModel;
use History\controllers\HistoryController;
class DocumentController
{
public function get(Request $request, Response $response)
{
$data = $request->getQueryParams();
$data['limit'] = (int)$data['limit'];
$data['offset'] = (int)$data['offset'];
$user = UserModel::getByEmail(['email' => $GLOBALS['email'], 'select' => ['id']]);
$documents = DocumentModel::getByUserId(['select' => ['id', 'reference', 'subject', 'status', 'count(1) OVER()'], 'userId' => $user['id'], 'limit' => $data['limit'], 'offset' => $data['offset']]);
foreach ($documents as $key => $document) {
$status = StatusModel::getById(['select' => ['label'], 'id' => $document['status']]);
$documents[$key]['statusDisplay'] = $status['label'];
$fullCount = $document['count'];
unset($documents[$key]['count']);
return $response->withJson(['documents' => $documents, 'fullCount' => $fullCount]);
public function getById(Request $request, Response $response, array $args)
{
if (!DocumentController::hasRightById(['id' => $args['id'], 'email' => $GLOBALS['email']])) {
return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
}
$document = DocumentModel::getById(['select' => ['*'], 'id' => $args['id']]);
if (empty($document)) {
return $response->withStatus(400)->withJson(['errors' => 'Document does not exist']);
}
$status = StatusModel::getById(['select' => ['label'], 'id' => $document['status']]);
$document['statusDisplay'] = $status['label'];
$actions = ActionModel::get(['select' => ['id', 'label', 'color', 'logo', 'event'], 'where' => ['previous_status_id = ?'], 'data' => [$document['status']]]);
$document['processingUserDisplay'] = UserModel::getLabelledUserById(['id' => $document['processing_user']]);
'where' => ['main_document_id = ?', 'type = ?'],
'data' => [$args['id'], 'DOC']
]);
$docserver = DocserverModel::getByType(['type' => 'DOC', 'select' => ['path']]);
if (empty($docserver['path']) || !file_exists($docserver['path'])) {
return $response->withStatus(400)->withJson(['errors' => 'Docserver does not exist']);
}
$pathToDocument = $docserver['path'] . $adr[0]['path'] . $adr[0]['filename'];
if (!file_exists($pathToDocument)) {
return $response->withStatus(404)->withJson(['errors' => 'Document not found on docserver']);
}
//TODO Commenté pour tests
// $fingerprint = DocserverController::getFingerPrint(['path' => $pathToDocument]);
// if ($adr[0]['fingerprint'] != $fingerprint) {
// return $response->withStatus(404)->withJson(['errors' => 'Fingerprints do not match']);
// }
$document['encodedDocument'] = base64_encode(file_get_contents($pathToDocument));
$document['attachments'] = AttachmentModel::getByDocumentId(['select' => ['id'], 'documentId' => $args['id']]);
return $response->withJson(['document' => $document]);
}
public function create(Request $request, Response $response)
{
$data = $request->getParams();
$check = Validator::stringType()->notEmpty()->validate($data['encodedZipDocument']);
$check = $check && Validator::stringType()->notEmpty()->validate($data['subject']);
$check = $check && Validator::stringType()->notEmpty()->validate($data['status']);
$check = $check && Validator::intVal()->notEmpty()->validate($data['processing_user']);
$check = $check && Validator::stringType()->notEmpty()->validate($data['sender']);
if (!$check) {
return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
}
$data['attachments'] = empty($data['attachments']) ? [] : $data['attachments'];
foreach ($data['attachments'] as $key => $attachment) {
$check = Validator::stringType()->notEmpty()->validate($attachment['encodedZipDocument']);
$check = $check && Validator::stringType()->notEmpty()->validate($attachment['subject']);
if (!$check) {
return $response->withStatus(400)->withJson(['errors' => "Missing data for attachment {$key}"]);
}
}
$encodedDocument = DocumentController::getEncodedDocumentFromEncodedZip(['encodedZipDocument' => $data['encodedZipDocument']]);
if (!empty($encodedDocument['errors'])) {
return $response->withStatus(500)->withJson(['errors' => $encodedDocument['errors']]);
}
$storeInfos = DocserverController::storeResourceOnDocServer([
'encodedFile' => $encodedDocument['encodedDocument'],
'format' => 'pdf',
'docserverType' => 'DOC'
]);
if (!empty($storeInfos['errors'])) {
return $response->withStatus(500)->withJson(['errors' => $storeInfos['errors']]);
}
$status = StatusModel::get(['select' => ['id'], 'where' => ['reference = ?'], 'data' => [$data['status']]]);
$data['status'] = $status[0]['id'];
DatabaseModel::beginTransaction();
$id = DocumentModel::create($data);
AdrModel::createDocumentAdr([
'documentId' => $id,
'type' => 'DOC',
'path' => $storeInfos['path'],
'filename' => $storeInfos['filename'],
'fingerprint' => $storeInfos['fingerprint']
]);
foreach ($data['attachments'] as $key => $value) {
$value['main_document_id'] = $id;
$attachment = AttachmentController::create($value);
if (!empty($attachment['errors'])) {
DatabaseModel::rollbackTransaction();
return $response->withStatus(500)->withJson(['errors' => "An error occured for attachment {$key} : {$attachment['errors']}"]);
}
}
DatabaseModel::commitTransaction();
return $response->withJson(['documentId' => $id]);
}
public function makeAction(Request $request, Response $response, array $args)
{
$data = $request->getParams();
ValidatorModel::notEmpty($data, ['action_id']);
foreach ($data['signatures'] as $signature) {
foreach (['fullPath', 'width', 'positionX', 'positionY', 'page'] as $value) {
if (empty($signature[$value])) {
return $response->withStatus(400)->withJson(['errors' => $value . ' is empty']);
}
if (!DocumentController::hasRightById(['id' => $args['id'], 'email' => $GLOBALS['email']])) {
return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
}
$action = ActionModel::getById(['select' => ['next_status_id', 'label'], 'id' => $data['action_id']]);
if (empty($action)) {
return $response->withStatus(403)->withJson(['errors' => 'Action does not exist']);
}
$adr = AdrModel::getDocumentsAdr([
'select' => ['path', 'filename'],
'where' => ['main_document_id = ?', 'type = ?'],
'data' => [$args['id'], 'DOC']
]);
if (empty($adr)) {
return $response->withStatus(400)->withJson(['errors' => 'Document does not exist in database']);
}
$docserver = DocserverModel::getByType(['type' => 'DOC', 'select' => ['path']]);
if (empty($docserver['path']) || !file_exists($docserver['path'])) {
return $response->withStatus(400)->withJson(['errors' => 'Docserver does not exist']);
}
$pathToDocument = $docserver['path'] . $adr[0]['path'] . $adr[0]['filename'];
if (!file_exists($pathToDocument)) {
return $response->withStatus(404)->withJson(['errors' => 'Document not found on docserver']);
}
$tmpPath = CoreConfigModel::getTmpPath();
$tmpFilename = $tmpPath . $GLOBALS['email'] . '_' . rand() . '_' . $adr[0]['filename'];
copy($pathToDocument, $tmpFilename);
$nbPages = $pdf->setSourceFile($tmpFilename);
$pdf->setPrintHeader(false);
for ($i = 1; $i <= $nbPages; $i++) {
$page = $pdf->importPage($i);
$size = $pdf->getTemplateSize($page);
$pdf->AddPage($size['orientation'], $size);
$pdf->useImportedPage($page);
$pdf->SetAutoPageBreak(false, 0);
$pdf->SetMargins(0, 0, 0);
if (!empty($data['signatures'])) {
foreach ($data['signatures'] as $signature) {
if ($signature['page'] == $i) {
if (preg_match('/^data:image\/(\w+);base64,/', $signature['fullPath'], $extension)) {
$data = substr($signature['fullPath'], strpos($signature['fullPath'], ',') + 1);
$extension = strtolower($extension[1]);
if ($extension != 'png') {
return $response->withStatus(400)->withJson(['errors' => 'Invalid image type']);
}
} else {
$data = $signature['fullPath'];
$image = base64_decode($data);
if ($image === false) {
return $response->withStatus(400)->withJson(['errors' => 'base64_decode failed']);
}
$imageTmpPath = $tmpPath . $GLOBALS['email'] . '_' . rand() . '_writing.png';
// $pdf->Image($imageTmpPath, $signature['positionX'], $signature['positionY']);
$pdf->SetY(0);
$html = '<img src="'.$signature['fullPath'].'"/>';
$pdf->writeHTML($html, true, false, true, false, '');
}
}
}
}
$fileContent = $pdf->Output('', 'S');
$storeInfos = DocserverController::storeResourceOnDocServer([
'encodedFile' => base64_encode($fileContent),
'format' => 'pdf',
]);
AdrModel::createDocumentAdr([
'documentId' => $args['id'],
'path' => $storeInfos['path'],
'filename' => $storeInfos['filename'],
'fingerprint' => $storeInfos['fingerprint']
]);
'where' => ['id = ?'],
'data' => [$args['id']]
]);
HistoryController::add([
'tableName' => 'main_documents',
'recordId' => $args['id'],
'eventType' => 'UP',
'moduleId' => 'document',
'eventId' => 'documentup',
]);
return $response->withJson(['success' => 'success']);
}
public static function hasRightById(array $args)
{
ValidatorModel::intVal($args, ['id']);
$user = UserModel::getByEmail(['email' => $GLOBALS['email'], 'select' => ['id']]);
$document = DocumentModel::get(['select' => [1], 'where' => ['processing_user = ?', 'id = ?'], 'data' => [$user['id'], $args['id']]]);
if (empty($document)) {
return false;
}
return true;
}
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
public static function getEncodedDocumentFromEncodedZip(array $args)
{
ValidatorModel::notEmpty($args, ['encodedZipDocument']);
ValidatorModel::stringType($args, ['encodedZipDocument']);
$tmpPath = CoreConfigModel::getTmpPath();
$zipDocumentOnTmp = $tmpPath . mt_rand() . '_parapheur.zip';
file_put_contents($zipDocumentOnTmp, base64_decode($args['encodedZipDocument']));
$zipArchive = new \ZipArchive();
$open = $zipArchive->open($zipDocumentOnTmp);
if ($open != true) {
return ['errors' => "getDocumentFromEncodedZip : $open"];
}
$dirOnTmp = $tmpPath . mt_rand() . '_parapheur';
if (!$zipArchive->extractTo($dirOnTmp)) {
return ['errors' => "getDocumentFromEncodedZip : Extract failed"];
}
$filesOnTmp = scandir($dirOnTmp);
foreach ($filesOnTmp as $fileOnTmp) {
if ($fileOnTmp != '.' && $fileOnTmp != '..') {
return ['encodedDocument' => base64_encode(file_get_contents("{$dirOnTmp}/{$fileOnTmp}"))];
}
}
return ['errors' => "getDocumentFromEncodedZip : No document was found in Zip"];
}