Something went wrong on our end
-
Guillaume Heurtier authoredGuillaume Heurtier authored
FolderController.php 34.76 KiB
<?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 Basket\models\BasketModel;
use Basket\models\GroupBasketModel;
use Entity\models\EntityModel;
use Folder\models\EntityFolderModel;
use Folder\models\FolderModel;
use Folder\models\ResourceFolderModel;
use Folder\models\UserPinnedFolderModel;
use Group\models\GroupModel;
use Group\models\ServiceModel;
use History\controllers\HistoryController;
use Resource\controllers\ResController;
use Resource\controllers\ResourceListController;
use Resource\models\ResModel;
use Resource\models\ResourceListModel;
use Respect\Validation\Validator;
use Slim\Http\Request;
use Slim\Http\Response;
use SrcCore\controllers\PreparedClauseController;
use SrcCore\models\DatabaseModel;
use SrcCore\models\ValidatorModel;
use User\models\UserModel;
class FolderController
{
public function get(Request $request, Response $response)
{
$folders = FolderController::getScopeFolders(['login' => $GLOBALS['userId']]);
$userEntities = EntityModel::getWithUserEntities(['select' => ['entities.id'], 'where' => ['user_id = ?'], 'data' => [$GLOBALS['userId']]]);
$userEntities = array_column($userEntities, 'id');
if (empty($userEntities)) {
$userEntities = 0;
}
$foldersWithResources = FolderModel::getWithEntitiesAndResources([
'select' => ['COUNT(DISTINCT resources_folders.res_id)', 'resources_folders.folder_id'],
'where' => ['(entities_folders.entity_id in (?) OR folders.user_id = ?)'],
'data' => [$userEntities, $GLOBALS['id']],
'groupBy' => ['resources_folders.folder_id']
]);
$tree = [];
foreach ($folders as $folder) {
$key = array_keys(array_column($foldersWithResources, 'folder_id'), $folder['id']);
$count = 0;
if (isset($key[0])) {
$count = $foldersWithResources[$key[0]]['count'];
}
$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'],
'countResources' => $count
];
if ($folder['level'] == 0) {
array_splice($tree, 0, 0, [$insert]);
} else {
$found = false;
foreach ($tree as $key => $branch) {
if ($branch['id'] == $folder['parent_id']) {
array_splice($tree, $key + 1, 0, [$insert]);
$found = true;
break;
}
}
if (!$found) {
$insert['level'] = 0;
$insert['parent_id'] = null;
$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];
$ownerInfo = UserModel::getById(['select' => ['firstname', 'lastname'], 'id' => $folder['user_id']]);
$folder['ownerDisplayName'] = $ownerInfo['firstname'] . ' ' . $ownerInfo['lastname'];
$folder['sharing']['entities'] = [];
if ($folder['public']) {
$entitiesFolder = EntityFolderModel::getByFolderId(['folder_id' => $args['id'], 'select' => ['entities_folders.entity_id', 'entities_folders.edition', 'entities.entity_label']]);
foreach ($entitiesFolder as $value) {
$canDelete = FolderController::areChildrenInPerimeter(['folderId' => $args['id']]);
$folder['sharing']['entities'][] = ['entity_id' => $value['entity_id'], 'edition' => $value['edition'], 'canDelete' => $canDelete, 'label' => $value['entity_label']];
}
}
return $response->withJson(['folder' => $folder]);
}
public function create(Request $request, Response $response)
{
$data = $request->getParsedBody();
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'] = null;
$owner = $GLOBALS['id'];
$public = false;
$level = 0;
} else {
$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;
}
$id = FolderModel::create([
'label' => $data['label'],
'public' => $public,
'user_id' => $owner,
'parent_id' => $data['parent_id'],
'level' => $level
]);
if ($public && !empty($data['parent_id'])) {
$entitiesSharing = EntityFolderModel::getByFolderId(['folder_id' => $data['parent_id'], 'select' => ['entities.id', 'entities_folders.edition']]);
foreach ($entitiesSharing as $entity) {
EntityFolderModel::create([
'folder_id' => $id,
'entity_id' => $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']);
}
if ($data['parent_id'] == $aArgs['id']) {
return $response->withStatus(400)->withJson(['errors' => 'Parent_id and id can not be the same']);
}
if (!empty($data['parent_id']) && FolderController::isParentFolder(['parent_id' => $data['parent_id'], 'id' => $aArgs['id']])) {
return $response->withStatus(400)->withJson(['errors' => 'parent_id does not exist or Id is a parent of parent_id']);
}
$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'] = null;
$level = 0;
} else {
$folderParent = FolderModel::getById(['id' => $data['parent_id'], 'select' => ['folders.id', 'parent_id', 'level']]);
$level = $folderParent['level'] + 1;
}
FolderController::updateChildren($aArgs['id'], $level);
FolderModel::update([
'set' => [
'label' => $data['label']
],
'where' => ['id = ?'],
'data' => [$aArgs['id']]
]);
if ($folder[0]['parent_id'] != $data['parent_id']) {
$childrenInPerimeter = FolderController::areChildrenInPerimeter(['folderId' => $aArgs['id']]);
if ($childrenInPerimeter || $folder[0]['user_id'] == $GLOBALS['id']) {
FolderModel::update([
'set' => [
'parent_id' => $data['parent_id'],
'level' => $level
],
'where' => ['id = ?'],
'data' => [$aArgs['id']]
]);
} else {
return $response->withStatus(400)->withJson(['errors' => 'Cannot move folder because at least one folder is out of your perimeter']);
}
}
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::boolType()->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' => 'Cannot share/unshare folder because at least 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(204);
}
public function folderSharing($aArgs = [])
{
$folder = FolderController::getScopeFolders(['login' => $GLOBALS['userId'], 'folderId' => $aArgs['folderId'], 'edition' => true]);
if (empty($folder[0])) {
return false;
}
FolderModel::update([
'set' => [
'public' => empty($aArgs['public']) ? 'false' : 'true',
],
'where' => ['id = ?'],
'data' => [$aArgs['folderId']]
]);
EntityFolderModel::deleteByFolderId(['folder_id' => $aArgs['folderId']]);
if ($aArgs['public'] && !empty($aArgs['sharing']['entities'])) {
foreach ($aArgs['sharing']['entities'] as $entity) {
EntityFolderModel::create([
'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) {
FolderController::folderSharing(['folderId' => $child['id'], 'public' => $aArgs['public'], 'sharing' => $aArgs['sharing']]);
}
}
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' => 'Cannot delete because at least 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(204);
}
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;
}
public static function areChildrenInPerimeter(array $aArgs = []) {
$folder = FolderController::getScopeFolders(['login' => $GLOBALS['userId'], 'folderId' => $aArgs['folderId'], 'edition' => true]);
if (empty($folder[0])) {
return false;
}
$children = FolderModel::getWithEntities([
'select' => ['distinct (folders.id), edition'],
'where' => ['parent_id = ?'],
'data' => [$aArgs['folderId']]
]);
if (!empty($children)) {
foreach ($children as $child) {
if ($child['edition'] == false or $child['edition'] == null) {
return false;
}
if (!FolderController::areChildrenInPerimeter(['folderId' => $child['id']])) {
return false;
}
}
}
return true;
}
public function getResourcesById(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']);
}
if (!FolderController::hasFolders(['folders' => [$args['id']], 'userId' => $GLOBALS['id']])) {
return $response->withStatus(400)->withJson(['errors' => 'Folder out of perimeter']);
}
$foldersResources = ResourceFolderModel::get(['select' => ['res_id'], 'where' => ['folder_id = ?'], 'data' => [$args['id']]]);
$foldersResources = array_column($foldersResources, 'res_id');
$formattedResources = [];
$allResources = [];
$count = 0;
if (!empty($foldersResources)) {
$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']]);
foreach ($rawResources as $resource) {
$allResources[] = $resource['res_id'];
}
$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['id'], 'TMP'],
'groupBy' => ['res_id_master']
]);
$select = [
'res_letterbox.res_id', 'res_letterbox.subject', 'res_letterbox.barcode', 'res_letterbox.alt_identifier',
'status.label_status AS "status.label_status"', 'status.img_filename AS "status.img_filename"', 'priorities.color AS "priorities.color"'
];
$tableFunction = ['status', 'priorities'];
$leftJoinFunction = ['res_letterbox.status = status.id', 'res_letterbox.priority = priorities.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
]);
}
$count = count($rawResources);
}
return $response->withJson(['resources' => $formattedResources, 'countResources' => $count, 'allResources' => $allResources]);
}
public function addResourcesById(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']);
}
$body = $request->getParsedBody();
if (!Validator::arrayType()->notEmpty()->validate($body['resources'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body resources is empty or not an array']);
}
if (!FolderController::hasFolders(['folders' => [$args['id']], 'userId' => $GLOBALS['id']])) {
return $response->withStatus(400)->withJson(['errors' => 'Folder out of perimeter']);
}
$foldersResources = ResourceFolderModel::get(['select' => ['res_id'], 'where' => ['folder_id = ?'], 'data' => [$args['id']]]);
$foldersResources = array_column($foldersResources, 'res_id');
$resourcesToClassify = array_diff($body['resources'], $foldersResources);
if (empty($resourcesToClassify)) {
return $response->withJson(['countResources' => count($foldersResources)]);
}
if (!ResController::hasRightByResId(['resId' => $resourcesToClassify, 'userId' => $GLOBALS['id']])) {
return $response->withStatus(400)->withJson(['errors' => 'Resources out of perimeter']);
}
foreach ($resourcesToClassify as $value) {
ResourceFolderModel::create(['folder_id' => $args['id'], 'res_id' => $value]);
}
HistoryController::add([
'tableName' => 'resources_folders',
'recordId' => $args['id'],
'eventType' => 'ADD',
'info' => _FOLDER_RESOURCES_ADDED . " : " . implode(", ", $resourcesToClassify) . " " . _FOLDER_TO_FOLDER . " " . $args['id'],
'moduleId' => 'folder',
'eventId' => 'folderResourceAdded',
]);
return $response->withJson(['countResources' => count($foldersResources) + count($resourcesToClassify)]);
}
public function removeResourcesById(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']);
}
if (!FolderController::hasFolders(['folders' => [$args['id']], 'userId' => $GLOBALS['id']])) {
return $response->withStatus(400)->withJson(['errors' => 'Folder out of perimeter']);
}
$foldersResources = ResourceFolderModel::get(['select' => ['res_id'], 'where' => ['folder_id = ?'], 'data' => [$args['id']]]);
$foldersResources = array_column($foldersResources, 'res_id');
$body = $request->getParsedBody();
if (!Validator::arrayType()->notEmpty()->validate($body['resources'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body resources is empty or not an array']);
}
$resourcesToUnclassify = array_intersect($foldersResources, $body['resources']);
if (empty($resourcesToUnclassify)) {
return $response->withJson(['countResources' => count($foldersResources)]);
}
if (!ResController::hasRightByResId(['resId' => $resourcesToUnclassify, 'userId' => $GLOBALS['id']])) {
return $response->withStatus(400)->withJson(['errors' => 'Resources out of perimeter']);
}
foreach ($resourcesToUnclassify as $value) {
ResourceFolderModel::delete(['where' => ['folder_id = ?', 'res_id = ?'], 'data' => [$args['id'], $value]]);
}
HistoryController::add([
'tableName' => 'resources_folders',
'recordId' => $args['id'],
'eventType' => 'DEL',
'info' => _FOLDER_RESOURCES_REMOVED . " : " . implode(", ", $resourcesToUnclassify) . " " . _FOLDER_TO_FOLDER . " " . $args['id'],
'moduleId' => 'folder',
'eventId' => 'folderResourceRemoved',
]);
return $response->withJson(['countResources' => count($foldersResources) - count($resourcesToUnclassify)]);
}
public function getBasketsFromFolder(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']);
}
if (!FolderController::hasFolders(['folders' => [$args['id']], 'userId' => $GLOBALS['id']])) {
return $response->withStatus(403)->withJson(['errors' => 'Folder out of perimeter']);
}
$foldersResource = ResourceFolderModel::get(['select' => [1], 'where' => ['folder_id = ?', 'res_id = ?'], 'data' => [$args['id'], $args['resId']]]);
if (empty($foldersResource)) {
return $response->withStatus(403)->withJson(['errors' => 'Resource out of perimeter']);
}
$baskets = BasketModel::getWithPreferences([
'select' => ['baskets.id', 'baskets.basket_name', 'baskets.basket_clause', 'users_baskets_preferences.group_serial_id', 'usergroups.group_desc'],
'where' => ['users_baskets_preferences.user_serial_id = ?'],
'data' => [$GLOBALS['id']]
]);
$groupsBaskets = [];
$inCheckedBaskets = [];
$outCheckedBaskets = [];
foreach ($baskets as $basket) {
if (in_array($basket['id'], $outCheckedBaskets)) {
continue;
} else {
if (!in_array($basket['id'], $inCheckedBaskets)) {
$preparedClause = PreparedClauseController::getPreparedClause(['clause' => $basket['basket_clause'], 'login' => $GLOBALS['userId']]);
$resource = ResModel::getOnView(['select' => [1], 'where' => ['res_id = ?', "({$preparedClause})"], 'data' => [$args['resId']]]);
if (empty($resource)) {
$outCheckedBaskets[] = $basket['id'];
continue;
}
}
$inCheckedBaskets[] = $basket['id'];
$groupsBaskets[] = ['groupId' => $basket['group_serial_id'], 'groupName' => $basket['group_desc'], 'basketId' => $basket['id'], 'basketName' => $basket['basket_name']];
}
}
return $response->withJson(['groupsBaskets' => $groupsBaskets]);
}
public function getFilters(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']);
}
if (!FolderController::hasFolders(['folders' => [$args['id']], 'userId' => $GLOBALS['id']])) {
return $response->withStatus(400)->withJson(['errors' => 'Folder out of perimeter']);
}
$foldersResources = ResourceFolderModel::get(['select' => ['res_id'], 'where' => ['folder_id = ?'], 'data' => [$args['id']]]);
$foldersResources = array_column($foldersResources, 'res_id');
if (empty($foldersResources)) {
return $response->withJson(['entities' => [], 'priorities' => [], 'categories' => [], 'statuses' => [], 'entitiesChildren' => []]);
}
$where = ['(res_id in (?))'];
$queryData = [$foldersResources];
$queryParams = $request->getQueryParams();
$filters = ResourceListController::getFormattedFilters(['where' => $where, 'queryData' => $queryData, 'queryParams' => $queryParams]);
return $response->withJson($filters);
}
// login (string) : Login of user connected
// folderId (integer) : Check specific folder
// edition (boolean) : whether user can edit or not
public static function getScopeFolders(array $aArgs)
{
$login = $aArgs['login'];
$userEntities = EntityModel::getWithUserEntities(['select' => ['entities.id'], 'where' => ['user_id = ?'], 'data' => [$login]]);
$userEntities = array_column($userEntities, 'id');
if (empty($userEntities)) {
$userEntities = 0;
}
$user = UserModel::getByLogin(['login' => $login, 'select' => ['id']]);
if ($aArgs['edition']) {
$edition = [1];
} else {
$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::getWithEntities([
'select' => ['distinct (folders.id)', 'folders.*'],
'where' => $where,
'data' => $data,
'orderBy' => ['level', 'label desc']
]);
return $folders;
}
public function pinFolder(Request $request, Response $response, array $args)
{
if (!Validator::numeric()->notEmpty()->validate($args['id'])) {
return $response->withStatus(400)->withJson(['errors' => 'Route id not found or 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']);
}
$alreadyPinned = UserPinnedFolderModel::get([
'select' => ['folder_id', 'user_id'],
'where' => ['folder_id = ?', 'user_id = ?'],
'data' => [$args['id'], $GLOBALS['id']]
]);
if (!empty($alreadyPinned)) {
return $response->withStatus(400)->withJson(['errors' => 'Folder is already pinned']);
}
UserPinnedFolderModel::create([
'folder_id' => $args['id'],
'user_id' => $GLOBALS['id']
]);
return $response->withStatus(204);
}
public function getPinnedFolders(Request $request, Response $response)
{
$folders = UserPinnedFolderModel::getById(['user_id' => $GLOBALS['id']]);
$foldersWithResources = FolderModel::getWithEntitiesAndResources([
'select' => ['COUNT(DISTINCT resources_folders.res_id)', 'resources_folders.folder_id'],
'where' => ['(folders.user_id = ?)'],
'data' => [$GLOBALS['id']],
'groupBy' => ['resources_folders.folder_id']
]);
$pinnedFolders = [];
foreach ($folders as $folder) {
$key = array_keys(array_column($foldersWithResources, 'folder_id'), $folder['id']);
$count = 0;
if (isset($key[0])) {
$count = $foldersWithResources[$key[0]]['count'];
}
$pinnedFolders[] = [
'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'],
'countResources' => $count
];
}
return $response->withJson(['folders' => $pinnedFolders]);
}
public function unpinFolder(Request $request, Response $response, array $args)
{
if (!Validator::numeric()->notEmpty()->validate($args['id'])) {
return $response->withStatus(400)->withJson(['errors' => 'Route id not found or 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']);
}
$alreadyPinned = UserPinnedFolderModel::get([
'select' => ['folder_id', 'user_id'],
'where' => ['folder_id = ?', 'user_id = ?'],
'data' => [$args['id'], $GLOBALS['id']]
]);
if (empty($alreadyPinned)) {
return $response->withStatus(400)->withJson(['errors' => 'Folder is not pinned']);
}
UserPinnedFolderModel::delete([
'where' => ['folder_id = ?', 'user_id = ?'],
'data' => [$args['id'], $GLOBALS['id']]
]);
return $response->withStatus(204);
}
private static function hasFolders(array $args)
{
ValidatorModel::notEmpty($args, ['folders', 'userId']);
ValidatorModel::arrayType($args, ['folders']);
ValidatorModel::intVal($args, ['userId']);
$user = UserModel::getById(['id' => $args['userId'], 'select' => ['user_id']]);
$entities = UserModel::getEntitiesById(['userId' => $user['user_id']]);
$entities = array_column($entities, 'id');
if (empty($entities)) {
$entities = [0];
}
$folders = FolderModel::getWithEntities([
'select' => ['count(distinct folders.id)'],
'where' => ['folders.id in (?)', '(user_id = ? OR entity_id in (?))'],
'data' => [$args['folders'], $args['userId'], $entities]
]);
if ($folders[0]['count'] != count($args['folders'])) {
return false;
}
return true;
}
private static function isParentFolder(array $args)
{
$parentInfo = FolderModel::getById(['id' => $args['parent_id'], 'select' => ['folders.id', 'parent_id']]);
if (empty($parentInfo) || $parentInfo['id'] == $args['id']) {
return true;
} elseif (!empty($parentInfo['parent_id'])) {
return FolderController::isParentFolder(['parent_id' => $parentInfo['parent_id'], 'id' => $args['id']]);
}
return false;
}
private static function updateChildren($parentId, $levelParent)
{
$folderChild = FolderModel::getChild(['id' => $parentId]);
if (!empty($folderChild)) {
foreach ($folderChild as $child) {
$level = $levelParent + 1;
FolderController::updateChildren($child['id'], $level);
}
$idsChildren = array_column($folderChild, 'id');
FolderModel::update([
'set' => [
'level' => $level
],
'where' => ['id in (?)'],
'data' => [$idsChildren]
]);
}
}
}