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 Folder Controller
*
* @author dev@maarch.org
*/
namespace Folder\controllers;
use Attachment\models\AttachmentModel;
use Folder\models\EntityFolderModel;
use Folder\models\ResourceFolderModel;
use History\controllers\HistoryController;
use Resource\controllers\ResourceListController;
use Resource\models\ResourceListModel;
use Respect\Validation\Validator;
use Slim\Http\Request;
use Slim\Http\Response;
use SrcCore\models\DatabaseModel;
class FolderController
{
public function get(Request $request, Response $response)
{
$folders = FolderController::getScopeFolders(['login' => $GLOBALS['userId']]);
$tree = [];
foreach ($folders as $folder) {
$insert = [
'name' => $folder['label'],
'id' => $folder['id'],
'label' => $folder['label'],
'public' => $folder['public'],
'user_id' => $folder['user_id'],
'parent_id' => $folder['parent_id'],
'level' => $folder['level'],
];
if ($folder['level'] == 0) {
$tree[] = $insert;
foreach ($tree as $key => $branch) {
if ($branch['id'] == $folder['parent_id']) {
array_splice($tree, $key + 1, 0, [$insert]);
if (!$found) {
$tree[] = $insert;
}
return $response->withJson(['folders' => $tree]);
public function getById(Request $request, Response $response, array $args)
if (!Validator::numeric()->notEmpty()->validate($args['id'])) {
return $response->withStatus(400)->withJson(['errors' => 'Route id is not an integer']);
$folder = FolderController::getScopeFolders(['login' => $GLOBALS['userId'], 'folderId' => $args['id']]);
if (empty($folder[0])) {
return $response->withStatus(400)->withJson(['errors' => 'Folder not found or out of your perimeter']);
$folder = $folder[0];
$folder['sharing']['entities'] = [];
if ($folder['public']) {
$entitiesFolder = EntityFolderModel::getByFolderId(['folder_id' => $args['id']]);
foreach ($entitiesFolder as $value) {
$folder['sharing']['entities'][] = ['entity_id' => $value['entity_id'], 'edition' => $value['edition']];
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
$foldersResources = ResourceFolderModel::get(['select' => ['res_id'], 'where' => ['folder_id = ?'], 'data' => [$args['id']]]);
$foldersResources = array_column($foldersResources, 'res_id');
$queryParams = $request->getQueryParams();
$queryParams['offset'] = (empty($queryParams['offset']) || !is_numeric($queryParams['offset']) ? 0 : (int)$queryParams['offset']);
$queryParams['limit'] = (empty($queryParams['limit']) || !is_numeric($queryParams['limit']) ? 10 : (int)$queryParams['limit']);
$allQueryData = ResourceListController::getResourcesListQueryData(['data' => $queryParams]);
if (!empty($allQueryData['order'])) {
$data['order'] = $allQueryData['order'];
}
$rawResources = ResourceListModel::getOnView([
'select' => ['res_id'],
'table' => $allQueryData['table'],
'leftJoin' => $allQueryData['leftJoin'],
'where' => array_merge(['res_id in (?)'], $allQueryData['where']),
'data' => array_merge([$foldersResources], $allQueryData['queryData']),
'orderBy' => empty($data['order']) ? ['creation_date'] : [$data['order']]
]);
$resIds = ResourceListController::getIdsWithOffsetAndLimit(['resources' => $rawResources, 'offset' => $queryParams['offset'], 'limit' => $queryParams['limit']]);
$formattedResources = [];
if (!empty($resIds)) {
$excludeAttachmentTypes = ['converted_pdf', 'print_folder'];
if (!ServiceModel::hasService(['id' => 'view_documents_with_notes', 'userId' => $GLOBALS['userId'], 'location' => 'attachments', 'type' => 'use'])) {
$excludeAttachmentTypes[] = 'document_with_notes';
}
$attachments = AttachmentModel::getOnView([
'select' => ['COUNT(res_id)', 'res_id_master'],
'where' => ['res_id_master in (?)', 'status not in (?)', 'attachment_type not in (?)', '((status = ? AND typist = ?) OR status != ?)'],
'data' => [$resIds, ['DEL', 'OBS'], $excludeAttachmentTypes, 'TMP', $GLOBALS['userId'], 'TMP'],
'groupBy' => ['res_id_master']
]);
$select = [
'res_letterbox.res_id', 'res_letterbox.subject', 'res_letterbox.barcode', 'mlb_coll_ext.alt_identifier',
'status.label_status AS "status.label_status"', 'status.img_filename AS "status.img_filename"'
];
$tableFunction = ['status', 'mlb_coll_ext'];
$leftJoinFunction = ['res_letterbox.status = status.id', 'res_letterbox.res_id = mlb_coll_ext.res_id'];
$order = 'CASE res_letterbox.res_id ';
foreach ($resIds as $key => $resId) {
$order .= "WHEN {$resId} THEN {$key} ";
}
$order .= 'END';
$resources = ResourceListModel::getOnResource([
'select' => $select,
'table' => $tableFunction,
'leftJoin' => $leftJoinFunction,
'where' => ['res_letterbox.res_id in (?)'],
'data' => [$resIds],
'orderBy' => [$order]
]);
$formattedResources = ResourceListController::getFormattedResources([
'resources' => $resources,
'userId' => $GLOBALS['id'],
'attachments' => $attachments,
'checkLocked' => false
]);
}
$folder['resources'] = $formattedResources;
$folder['countResources'] = count($rawResources);
//TODO Get default action
return $response->withJson(['folder' => $folder]);
}
public function create(Request $request, Response $response)
{
$data = $request->getParams();
if (!Validator::stringType()->notEmpty()->validate($data['label'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body label is empty or not a string']);
}
if (!empty($data['parent_id']) && !Validator::intval()->validate($data['parent_id'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body parent_id is not a numeric']);
}
if (empty($data['parent_id'])) {
$data['parent_id'] = 0;
$owner = $GLOBALS['id'];
$public = false;
$folder = FolderController::getScopeFolders(['login' => $GLOBALS['userId'], 'folderId' => $data['parent_id'], 'edition' => true]);
if (empty($folder[0])) {
return $response->withStatus(400)->withJson(['errors' => 'Parent Folder not found or out of your perimeter']);
}
$owner = $folder[0]['user_id'];
$public = $folder[0]['public'];
$level = $folder[0]['level'] + 1;
'label' => $data['label'],
'public' => $public,
'user_id' => $owner,
'parent_id' => $data['parent_id'],
'level' => $level
if ($public) {
$entitiesSharing = EntityFolderModel::getByFolderId(['folder_id' => $data['parent_id']]);
foreach ($entitiesSharing as $entity) {
EntityFolderModel::create([
'folder_id' => $id,
'entity_id' => $entity['entity_id'],
'edition' => $entity['edition'],
]);
}
}
HistoryController::add([
'tableName' => 'folders',
'recordId' => $id,
'eventType' => 'ADD',
'info' => _FOLDER_CREATION . " : {$data['label']}",
'moduleId' => 'folder',
'eventId' => 'folderCreation',
]);
return $response->withJson(['folder' => $id]);
}
public function update(Request $request, Response $response, array $aArgs)
{
$data = $request->getParams();
if (!Validator::numeric()->notEmpty()->validate($aArgs['id'])) {
return $response->withStatus(400)->withJson(['errors' => 'Query id is empty or not an integer']);
}
if (!Validator::stringType()->notEmpty()->validate($data['label'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body label is empty or not a string']);
}
if (!empty($data['parent_id']) &&!Validator::intval()->validate($data['parent_id'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body parent_id is not a numeric']);
}
$folder = FolderController::getScopeFolders(['login' => $GLOBALS['userId'], 'folderId' => $aArgs['id'], 'edition' => true]);
if (empty($folder[0])) {
return $response->withStatus(400)->withJson(['errors' => 'Folder not found or out of your perimeter']);
}
if (empty($data['parent_id'])) {
$data['parent_id'] = 0;
$folder = FolderController::getScopeFolders(['login' => $GLOBALS['userId'], 'folderId' => $data['parent_id']]);
if (empty($folder[0])) {
return $response->withStatus(400)->withJson(['errors' => 'Parent Folder not found or out of your perimeter']);
}
$level = $folder[0]['level'] + 1;
FolderModel::update([
'set' => [
'label' => $data['label'],
'parent_id' => $data['parent_id'],
'level' => $level
],
'where' => ['id = ?'],
'data' => [$aArgs['id']]
]);
HistoryController::add([
'tableName' => 'folders',
'recordId' => $aArgs['id'],
'eventType' => 'UP',
'info' => _FOLDER_MODIFICATION . " : {$data['label']}",
'moduleId' => 'folder',
'eventId' => 'folderModification',
]);
return $response->withStatus(200);
}
public function sharing(Request $request, Response $response, array $aArgs)
{
$data = $request->getParams();
if (!Validator::numeric()->notEmpty()->validate($aArgs['id'])) {
return $response->withStatus(400)->withJson(['errors' => 'Query id is empty or not an integer']);
}
if (!Validator::boolVal()->validate($data['public'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body public is empty or not a boolean']);
}
if ($data['public'] && !isset($data['sharing']['entities'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body sharing/entities does not exists']);
}
DatabaseModel::beginTransaction();
$sharing = FolderController::folderSharing(['folderId' => $aArgs['id'], 'public' => $data['public'], 'sharing' => $data['sharing']]);
if (!$sharing) {
DatabaseModel::rollbackTransaction();
return $response->withStatus(400)->withJson(['errors' => 'Can not share/unshare folder because almost one folder is out of your perimeter']);
}
DatabaseModel::commitTransaction();
HistoryController::add([
'tableName' => 'folders',
'recordId' => $aArgs['id'],
'eventType' => 'UP',
'info' => _FOLDER_SHARING_MODIFICATION . " : {$data['label']}",
'moduleId' => 'folder',
'eventId' => 'folderModification',
]);
return $response->withStatus(200);
}
public function folderSharing($aArgs = [])
{
$folder = FolderController::getScopeFolders(['login' => $GLOBALS['userId'], 'folderId' => $aArgs['folderId'], 'edition' => true]);
FolderModel::update([
'set' => [
'public' => empty($aArgs['public']) ? 'false' : 'true',
'data' => [$aArgs['folderId']]
EntityFolderModel::deleteByFolderId(['folder_id' => $aArgs['folderId']]);
if ($aArgs['public'] && !empty($aArgs['sharing']['entities'])) {
foreach ($aArgs['sharing']['entities'] as $entity) {
'folder_id' => $aArgs['folderId'],
'entity_id' => $entity['entity_id'],
'edition' => $entity['edition'],
]);
$folderChild = FolderModel::getChild(['id' => $aArgs['folderId'], 'select' => ['id']]);
if (!empty($folderChild)) {
foreach ($folderChild as $child) {
$sharing = FolderController::folderSharing(['folderId' => $child['id'], 'public' => $aArgs['public'], 'sharing' => $aArgs['sharing']]);
if (!$sharing) {
return false;
}
}
}
return true;
}
public function delete(Request $request, Response $response, array $aArgs)
{
if (!Validator::numeric()->notEmpty()->validate($aArgs['id'])) {
return $response->withStatus(400)->withJson(['errors' => 'Query id is empty or not an integer']);
}
$folder = FolderController::getScopeFolders(['login' => $GLOBALS['userId'], 'folderId' => $aArgs['id'], 'edition' => true]);
DatabaseModel::beginTransaction();
$deletion = FolderController::folderDeletion(['folderId' => $aArgs['id']]);
if (!$deletion) {
DatabaseModel::rollbackTransaction();
return $response->withStatus(400)->withJson(['errors' => 'Can not delete because almost one folder is out of your perimeter']);
}
DatabaseModel::commitTransaction();
HistoryController::add([
'tableName' => 'folder',
'recordId' => $aArgs['id'],
'eventType' => 'DEL',
'info' => _FOLDER_SUPPRESSION . " : {$folder[0]['label']}",
'moduleId' => 'folder',
'eventId' => 'folderSuppression',
]);
return $response->withStatus(200);
}
public static function folderDeletion(array $aArgs = [])
{
$folder = FolderController::getScopeFolders(['login' => $GLOBALS['userId'], 'folderId' => $aArgs['folderId'], 'edition' => true]);
if (empty($folder[0])) {
return false;
}
FolderModel::delete(['where' => ['id = ?'], 'data' => [$aArgs['folderId']]]);
EntityFolderModel::deleteByFolderId(['folder_id' => $aArgs['folderId']]);
ResourceFolderModel::delete(['where' => ['folder_id = ?'], 'data' => [$aArgs['folderId']]]);
$folderChild = FolderModel::getChild(['id' => $aArgs['folderId'], 'select' => ['id']]);
if (!empty($folderChild)) {
foreach ($folderChild as $child) {
$deletion = FolderController::folderDeletion(['folderId' => $child['id']]);
if (!$deletion) {
return false;
}
}
}
return true;
}
// login (string) : Login of user connected
// folderId (integer) : Check specific folder
// edition (boolean) : whether user can edit or not
private static function getScopeFolders(array $aArgs)
{
$login = $aArgs['login'];
$userEntities = EntityModel::getEntitiesByUserId([
'select' => ['entities.id'],
'user_id' => $login
]);
$userEntities = array_column($userEntities, 'id');
if (empty($userEntities)) {
$userEntities = 0;
}
$user = UserModel::getByLogin(['login' => $login, 'select' => ['id']]);
$edition = [0, 1, null];
}
$where = ['(user_id = ? OR (entity_id in (?) AND entities_folders.edition in (?)))'];
$data = [$user['id'], $userEntities, $edition];
if (!empty($aArgs['folderId'])) {
$where[] = 'folders.id = ?';
$data[] = $aArgs['folderId'];
}
$folders = FolderModel::get([
'select' => ['distinct (folders.id)', 'folders.*'],
'where' => $where,
'data' => $data,
'order_by' => ['level']
]);
return $folders;
}