From 9f4ea854c856a592d44aae3cfacd4df0c2f10c52 Mon Sep 17 00:00:00 2001
From: Guillaume Heurtier <guillaume.heurtier@maarch.org>
Date: Tue, 11 Feb 2020 11:22:51 +0100
Subject: [PATCH] FEAT #12471 TIME 2:00 refactor create/update tags

---
 .../resource/controllers/ExportController.php |  4 +-
 .../resource/controllers/ResController.php    | 10 +--
 src/app/tag/controllers/TagController.php     | 75 +++++++++++++++++--
 .../{TagResModel.php => ResourceTagModel.php} | 12 +--
 src/app/tag/models/TagModel.php               |  9 ++-
 5 files changed, 89 insertions(+), 21 deletions(-)
 rename src/app/tag/models/{TagResModel.php => ResourceTagModel.php} (89%)

diff --git a/src/app/resource/controllers/ExportController.php b/src/app/resource/controllers/ExportController.php
index 792e45283c8..79020c633fc 100644
--- a/src/app/resource/controllers/ExportController.php
+++ b/src/app/resource/controllers/ExportController.php
@@ -33,7 +33,7 @@ use SrcCore\controllers\PreparedClauseController;
 use SrcCore\models\TextFormatModel;
 use SrcCore\models\ValidatorModel;
 use Tag\models\TagModel;
-use Tag\models\TagResModel;
+use Tag\models\ResourceTagModel;
 use User\models\UserModel;
 
 require_once 'core/class/Url.php';
@@ -475,7 +475,7 @@ class ExportController
         }
 
         foreach ($args['chunkedResIds'] as $resIds) {
-            $tagsRes = TagResModel::get([
+            $tagsRes = ResourceTagModel::get([
                 'select'    => ['tag_id', 'res_id'],
                 'where'     => ['res_id in (?)'],
                 'data'      => [$resIds],
diff --git a/src/app/resource/controllers/ResController.php b/src/app/resource/controllers/ResController.php
index 2f1fab45b28..10e0303bf9e 100755
--- a/src/app/resource/controllers/ResController.php
+++ b/src/app/resource/controllers/ResController.php
@@ -48,7 +48,7 @@ use SrcCore\controllers\PreparedClauseController;
 use SrcCore\models\CoreConfigModel;
 use SrcCore\models\ValidatorModel;
 use Status\models\StatusModel;
-use Tag\models\TagResModel;
+use Tag\models\ResourceTagModel;
 use User\models\UserModel;
 
 class ResController extends ResourceControlController
@@ -221,7 +221,7 @@ class ResController extends ResourceControlController
             ]);
             $formattedData['folders'] = array_column($folders, 'folder_id');
 
-            $tags = TagResModel::get(['select' => ['tag_id'], 'where' => ['res_id = ?'], 'data' => [$args['resId']]]);
+            $tags = ResourceTagModel::get(['select' => ['tag_id'], 'where' => ['res_id = ?'], 'data' => [$args['resId']]]);
             $formattedData['tags'] = array_column($tags, 'tag_id');
         } else {
             $followed = UserFollowedResourceModel::get([
@@ -978,7 +978,7 @@ class ResController extends ResourceControlController
         }
         if (!empty($body['tags'])) {
             foreach ($body['tags'] as $tag) {
-                TagResModel::create(['res_id' => $args['resId'], 'tag_id' => $tag]);
+                ResourceTagModel::create(['res_id' => $args['resId'], 'tag_id' => $tag]);
             }
         }
         if (!empty($body['senders'])) {
@@ -1023,10 +1023,10 @@ class ResController extends ResourceControlController
                 ResourceFolderModel::create(['res_id' => $args['resId'], 'folder_id' => $folder]);
             }
         }
-        TagResModel::delete(['where' => ['res_id = ?'], 'data' => [$args['resId']]]);
+        ResourceTagModel::delete(['where' => ['res_id = ?'], 'data' => [$args['resId']]]);
         if (!empty($body['tags'])) {
             foreach ($body['tags'] as $tag) {
-                TagResModel::create(['res_id' => $args['resId'], 'tag_id' => $tag]);
+                ResourceTagModel::create(['res_id' => $args['resId'], 'tag_id' => $tag]);
             }
         }
         ResourceContactModel::delete(['where' => ['res_id = ?'], 'data' => [$args['resId']]]);
diff --git a/src/app/tag/controllers/TagController.php b/src/app/tag/controllers/TagController.php
index cb730ce53b8..59b3271d216 100644
--- a/src/app/tag/controllers/TagController.php
+++ b/src/app/tag/controllers/TagController.php
@@ -19,7 +19,7 @@ use Respect\Validation\Validator;
 use Slim\Http\Request;
 use Slim\Http\Response;
 use Tag\models\TagModel;
-use Tag\models\TagResModel;
+use Tag\models\ResourceTagModel;
 
 class TagController
 {
@@ -61,10 +61,58 @@ class TagController
             return $response->withStatus(400)->withJson(['errors' => 'Body label has more than 128 characters']);
         }
 
+        $parent = null;
+        if (!empty($body['parentId'])) {
+            if (!Validator::intVal()->validate($body['parentId'])) {
+                return $response->withStatus(400)->withJson(['errors' => 'Body parentId is not an integer']);
+            }
+            $parent = TagModel::getById(['id' => $body['parentId'], 'select' => ['id']]);
+            if (empty($parent)) {
+                return $response->withStatus(400)->withJson(['errors' => 'Parent tag does not exist']);
+            }
+            $parent = $parent['id'];
+        }
+
+        $links = json_encode([]);
+        if (!empty($body['links'])) {
+            if (!Validator::arrayType()->validate($body['links'])) {
+                return $response->withStatus(400)->withJson(['errors' => 'Body links is not an integer']);
+            }
+            $listTags = [];
+            foreach ($body['links'] as $link) {
+                if (!Validator::intVal()->validate($link)) {
+                    return $response->withStatus(400)->withJson(['errors' => 'Body links element is not an integer']);
+                }
+                $listTags[] = (string)$link;
+            }
+            $tags = TagModel::get([
+                'select' => ['count(1)'],
+                'where'  => ['id in (?)'],
+                'data'   => [$body['links']]
+            ]);
+            if ($tags[0]['count'] != count($body['links'])) {
+                return $response->withStatus(404)->withJson(['errors' => 'Tag(s) not found']);
+            }
+
+            $links = json_encode($listTags);
+        }
+
         $id = TagModel::create([
-            'label' => $body['label']
+            'label'       => $body['label'],
+            'description' => $body['description'] ?? null,
+            'parentId'    => $parent,
+            'links'       => $links,
+            'usage'       => $body['usage'] ?? null
         ]);
 
+        if (!empty($body['links'])) {
+            TagModel::update([
+                'postSet' => ['links' => "jsonb_insert(links, '{0}', '\"{$id}\"')"],
+                'where'   => ['id in (?)', "(links @> ?) = false"],
+                'data'    => [$body['links'], "\"{$id}\""]
+            ]);
+        }
+
         HistoryController::add([
             'tableName' => 'tags',
             'recordId'  => $id,
@@ -96,9 +144,24 @@ class TagController
             return $response->withStatus(400)->withJson(['errors' => 'Body label has more than 128 characters']);
         }
 
+        $parent = null;
+        if (!empty($body['parentId'])) {
+            if (!Validator::intVal()->validate($body['parentId'])) {
+                return $response->withStatus(400)->withJson(['errors' => 'Body parentId is not an integer']);
+            }
+            $parent = TagModel::getById(['id' => $body['parentId'], 'select' => ['id']]);
+            if (empty($parent)) {
+                return $response->withStatus(400)->withJson(['errors' => 'Parent tag does not exist']);
+            }
+            $parent = $parent['id'];
+        }
+
         TagModel::update([
             'set' => [
-                'label' => $body['label']
+                'label'       => $body['label'],
+                'description' => $body['description'] ?? null,
+                'parentId'    => $parent,
+                'usage'       => $body['usage'] ?? null
             ],
             'where' => ['id = ?'],
             'data' => [$args['id']]
@@ -174,13 +237,13 @@ class TagController
             return $response->withStatus(404)->withJson(['errors' => 'Merge tag not found']);
         }
 
-        $tagResMaster = TagResModel::get([
+        $tagResMaster = ResourceTagModel::get([
            'where'  => ['tag_id = ?'],
             'data'  => [$tagMaster['id']]
         ]);
         $tagResMaster = array_column($tagResMaster, 'res_id');
 
-        TagResModel::update([
+        ResourceTagModel::update([
            'set'    => [
                'tag_id' => $tagMaster['id']
            ],
@@ -188,7 +251,7 @@ class TagController
            'data'   => [$tagMerge['id'], $tagResMaster]
         ]);
 
-        TagResModel::delete([
+        ResourceTagModel::delete([
            'where'  => ['tag_id = ?'],
            'data'   => [$tagMerge['id']]
         ]);
diff --git a/src/app/tag/models/TagResModel.php b/src/app/tag/models/ResourceTagModel.php
similarity index 89%
rename from src/app/tag/models/TagResModel.php
rename to src/app/tag/models/ResourceTagModel.php
index 78f363ec700..f99f8a154f3 100644
--- a/src/app/tag/models/TagResModel.php
+++ b/src/app/tag/models/ResourceTagModel.php
@@ -8,7 +8,7 @@
  */
 
 /**
- * @brief Tag Res Model
+ * @brief Resource Tag Model
  * @author dev@maarch.org
  */
 
@@ -17,7 +17,7 @@ namespace Tag\models;
 use SrcCore\models\DatabaseModel;
 use SrcCore\models\ValidatorModel;
 
-class TagResModel
+class ResourceTagModel
 {
 
     public static function get(array $aArgs)
@@ -27,7 +27,7 @@ class TagResModel
 
         $tags = DatabaseModel::select([
             'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
-            'table'     => ['tag_res'],
+            'table'     => ['resources_tags'],
             'where'     => empty($aArgs['where']) ? [] : $aArgs['where'],
             'data'      => empty($aArgs['data']) ? [] : $aArgs['data'],
             'order_by'  => empty($aArgs['orderBy']) ? [] : $aArgs['orderBy'],
@@ -43,7 +43,7 @@ class TagResModel
         ValidatorModel::intVal($args, ['res_id', 'tag_id']);
 
         DatabaseModel::insert([
-            'table'         => 'tag_res',
+            'table'         => 'resources_tags',
             'columnsValues' => [
                 'res_id'    => $args['res_id'],
                 'tag_id'    => $args['tag_id']
@@ -59,7 +59,7 @@ class TagResModel
         ValidatorModel::arrayType($args, ['set', 'where', 'data']);
 
         DatabaseModel::update([
-            'table'     => 'tag_res',
+            'table'     => 'resources_tags',
             'set'       => empty($args['set']) ? [] : $args['set'],
             'where'     => $args['where'],
             'data'      => empty($args['data']) ? [] : $args['data']
@@ -74,7 +74,7 @@ class TagResModel
         ValidatorModel::arrayType($args, ['where', 'data']);
 
         DatabaseModel::delete([
-            'table' => 'tag_res',
+            'table' => 'resources_tags',
             'where' => $args['where'],
             'data'  => $args['data']
         ]);
diff --git a/src/app/tag/models/TagModel.php b/src/app/tag/models/TagModel.php
index c09d73a087e..55c7d7dc2eb 100644
--- a/src/app/tag/models/TagModel.php
+++ b/src/app/tag/models/TagModel.php
@@ -66,8 +66,12 @@ class TagModel
         DatabaseModel::insert([
             'table'         => 'tags',
             'columnsValues' => [
-                'id'        => $nextSequenceId,
-                'label'     => $args['label'],
+                'id'          => $nextSequenceId,
+                'label'       => $args['label'],
+                'description' => $args['description'] ?? null,
+                'parent_id'   => $args['parentId'] ?? null,
+                'links'       => $args['links'] ?? json_encode('[]'),
+                'usage'       => $args['usage'] ?? null
             ]
         ]);
 
@@ -96,6 +100,7 @@ class TagModel
         DatabaseModel::update([
             'table'     => 'tags',
             'set'       => empty($args['set']) ? [] : $args['set'],
+            'postSet'   => empty($args['postSet']) ? [] : $args['postSet'],
             'where'     => $args['where'],
             'data'      => empty($args['data']) ? [] : $args['data']
         ]);
-- 
GitLab