From 018b19173d254b441020004f058ceec891113bd3 Mon Sep 17 00:00:00 2001
From: Guillaume Heurtier <guillaume.heurtier@maarch.org>
Date: Thu, 17 Oct 2019 10:43:31 +0200
Subject: [PATCH] FEAT #11454 TIME 1:45 pin/unpin folders

---
 rest/index.php                                |  4 +
 .../folder/controllers/FolderController.php   | 95 ++++++++++++++++++-
 .../folder/models/UserPinnedFolderModel.php   | 70 ++++++++++++++
 3 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100644 src/app/folder/models/UserPinnedFolderModel.php

diff --git a/rest/index.php b/rest/index.php
index 12d19cb2e2a..fd9312de726 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -203,6 +203,10 @@ $app->delete('/folders/{id}/resources', \Folder\controllers\FolderController::cl
 $app->get('/folders/{id}/resources/{resId}/baskets', \Folder\controllers\FolderController::class . ':getBasketsFromFolder');
 $app->get('/folders/{id}/filters', \Folder\controllers\FolderController::class . ':getFilters');
 $app->put('/folders/{id}/sharing', \Folder\controllers\FolderController::class . ':sharing');
+$app->get('/pinnedFolders', \Folder\controllers\FolderController::class . ':getPinnedFolders');
+$app->put('/folders/{id}/pin', \Folder\controllers\FolderController::class . ':pinFolder');
+$app->delete('/folders/{id}/unpin', \Folder\controllers\FolderController::class . ':unpinFolder');
+
 
 //Groups
 $app->get('/groups', \Group\controllers\GroupController::class . ':get');
diff --git a/src/app/folder/controllers/FolderController.php b/src/app/folder/controllers/FolderController.php
index ec7fee76932..94718638a57 100755
--- a/src/app/folder/controllers/FolderController.php
+++ b/src/app/folder/controllers/FolderController.php
@@ -21,6 +21,7 @@ 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;
@@ -683,7 +684,99 @@ class FolderController
         return $folders;
     }
 
-    public static function hasFolders(array $args)
+    public function pinFolder(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']);
+        }
+
+        $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, array $args)
+    {
+        $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 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']);
diff --git a/src/app/folder/models/UserPinnedFolderModel.php b/src/app/folder/models/UserPinnedFolderModel.php
new file mode 100644
index 00000000000..15c3112ecc8
--- /dev/null
+++ b/src/app/folder/models/UserPinnedFolderModel.php
@@ -0,0 +1,70 @@
+<?php
+
+
+namespace Folder\models;
+
+
+use SrcCore\models\DatabaseModel;
+use SrcCore\models\ValidatorModel;
+
+class UserPinnedFolderModel
+{
+    public static function create(array $args)
+    {
+        ValidatorModel::notEmpty($args, ['folder_id', 'user_id']);
+        ValidatorModel::intVal($args, ['entity_id', 'user_id']);
+
+        DatabaseModel::insert([
+            'table'     => 'users_pinned_folders',
+            'columnsValues' => [
+                'folder_id'  => $args['folder_id'],
+                'user_id'  => $args['user_id'],
+            ]
+        ]);
+
+        return true;
+    }
+
+    public static function getById(array $args = [])
+    {
+        ValidatorModel::notEmpty($args, ['user_id']);
+        ValidatorModel::intVal($args, ['user_id']);
+
+        $pinnedFolders = DatabaseModel::select([
+            'select'    => empty($args['select']) ? ['*'] : $args['select'],
+            'table'     => ['users_pinned_folders', 'folders'],
+            'left_join' => ['users_pinned_folders.folder_id = folders.id'],
+            'where'     => ['users_pinned_folders.user_id = ?'],
+            'data'      => [$args['user_id']],
+            'order_by'  => empty($args['orderBy']) ? ['label'] : $args['orderBy']
+        ]);
+
+        return $pinnedFolders;
+    }
+
+    public static function get(array $aArgs)
+    {
+        $folders = DatabaseModel::select([
+            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
+            'table'     => ['users_pinned_folders'],
+            'where'     => empty($aArgs['where']) ? [] : $aArgs['where'],
+            'data'      => empty($aArgs['data']) ? [] : $aArgs['data'],
+        ]);
+
+        return $folders;
+    }
+
+    public static function delete(array $args)
+    {
+        ValidatorModel::notEmpty($args, ['where', 'data']);
+        ValidatorModel::arrayType($args, ['where', 'data']);
+
+        DatabaseModel::delete([
+            'table' => 'users_pinned_folders',
+            'where' => $args['where'],
+            'data'  => $args['data']
+        ]);
+
+        return true;
+    }
+}
\ No newline at end of file
-- 
GitLab