From 17d3784a21a5e979dd56ea731da624657c203fba Mon Sep 17 00:00:00 2001
From: Guillaume Heurtier <guillaume.heurtier@maarch.org>
Date: Mon, 14 Oct 2019 14:50:18 +0200
Subject: [PATCH] FEAT #11780 TIME 2:00 added merging tags

---
 rest/index.php                            |  1 +
 src/app/tag/controllers/TagController.php | 72 ++++++++++++++++++++++
 src/app/tag/models/TagModel.php           | 75 +++++++++++++++++++++++
 3 files changed, 148 insertions(+)

diff --git a/rest/index.php b/rest/index.php
index 683f2b8d979..57779cced98 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -373,6 +373,7 @@ $app->get('/tags', \Tag\controllers\TagController::class . ':get');
 $app->post('/tags', \Tag\controllers\TagController::class . ':create');
 $app->get('/tags/{id}', \Tag\controllers\TagController::class . ':getById');
 $app->put('/tags/{id}', \Tag\controllers\TagController::class . ':update');
+$app->put('/tags/{id}/merge', \Tag\controllers\TagController::class . ':merge');
 $app->delete('/tags/{id}', \Tag\controllers\TagController::class . ':delete');
 
 //Templates
diff --git a/src/app/tag/controllers/TagController.php b/src/app/tag/controllers/TagController.php
index f39220960ca..c24a0ee5583 100644
--- a/src/app/tag/controllers/TagController.php
+++ b/src/app/tag/controllers/TagController.php
@@ -152,4 +152,76 @@ class TagController
 
         return $response->withStatus(204);
     }
+
+    public function merge(Request $request, Response $response, array $args)
+    {
+        if (!ServiceModel::hasService(['id' => 'admin_tag', 'userId' => $GLOBALS['userId'], 'location' => 'apps', 'type' => 'admin'])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']);
+        }
+
+        $body = $request->getParsedBody();
+
+        if (!Validator::intVal()->notEmpty()->validate($args['id'])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Route idMaster must be an integer val']);
+        }
+
+        $tagMaster = TagModel::getById(['id' => $args['id']]);
+        if (empty($tagMaster)) {
+            return $response->withStatus(404)->withJson(['errors' => 'Master tag not found']);
+        }
+
+        if (!Validator::intVal()->notEmpty()->validate($body['idMerge'])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Body idMerge must be an integer val']);
+        }
+
+        $tagMerge = TagModel::getById(['id' => $body['idMerge']]);
+        if (empty($tagMerge)) {
+            return $response->withStatus(404)->withJson(['errors' => 'Merge tag not found']);
+        }
+
+        $tagResMaster = TagModel::getTagRes([
+           'where'  => ['tag_id = ?'],
+            'data'  => [$tagMaster['id']]
+        ]);
+        $tagResMaster = array_column($tagResMaster, 'res_id');
+
+        TagModel::updateTagRes([
+           'set'    => [
+               'tag_id' => $tagMaster['id']
+           ],
+           'where'  => ['tag_id = ?', 'res_id not in (?)'],
+           'data'   => [$tagMerge['id'], $tagResMaster]
+        ]);
+
+        TagModel::deleteTagRes([
+           'where'  => ['tag_id = ?'],
+           'data'   => [$tagMerge['id']]
+        ]);
+
+        $tagResEntities = TagModel::getTagEntities([
+            'where'  => ['tag_id = ?'],
+            'data'  => [$tagMaster['id']]
+        ]);
+        $tagResEntities = array_column($tagResEntities, 'entity_id');
+
+        TagModel::updateTagEntities([
+           'set'    => [
+               'tag_id' => $tagMaster['id']
+           ],
+           'where'  => ['tag_id = ?', 'entity_id not in (?)'],
+           'data'   => [$tagMerge['id'], $tagResEntities]
+        ]);
+
+        TagModel::deleteTagEntities([
+           'where'  => ['tag_id = ?'],
+           'data'   => [$tagMerge['id']]
+        ]);
+
+        TagModel::delete([
+            'where' => ['id = ?'],
+            'data'  => [$tagMerge['id']]
+        ]);
+
+        return $response->withStatus(204);
+    }
 }
diff --git a/src/app/tag/models/TagModel.php b/src/app/tag/models/TagModel.php
index 799e6523d52..3054280fc88 100644
--- a/src/app/tag/models/TagModel.php
+++ b/src/app/tag/models/TagModel.php
@@ -119,4 +119,79 @@ class TagModel
 
         return true;
     }
+
+    public static function updateTagRes(array $args)
+    {
+        ValidatorModel::notEmpty($args, ['where']);
+        ValidatorModel::arrayType($args, ['set', 'where', 'data']);
+
+        DatabaseModel::update([
+            'table'     => 'tag_res',
+            'set'       => empty($args['set']) ? [] : $args['set'],
+            'where'     => $args['where'],
+            'data'      => empty($args['data']) ? [] : $args['data']
+        ]);
+
+        return true;
+    }
+
+    public static function deleteTagRes(array $args)
+    {
+        ValidatorModel::notEmpty($args, ['where', 'data']);
+        ValidatorModel::arrayType($args, ['where', 'data']);
+
+        DatabaseModel::delete([
+            'table' => 'tag_res',
+            'where' => $args['where'],
+            'data'  => $args['data']
+        ]);
+
+        return true;
+    }
+
+    public static function updateTagEntities(array $args)
+    {
+        ValidatorModel::notEmpty($args, ['where']);
+        ValidatorModel::arrayType($args, ['set', 'where', 'data']);
+
+        DatabaseModel::update([
+            'table'     => 'tags_entities',
+            'set'       => empty($args['set']) ? [] : $args['set'],
+            'where'     => $args['where'],
+            'data'      => empty($args['data']) ? [] : $args['data']
+        ]);
+
+        return true;
+    }
+
+    public static function deleteTagEntities(array $args)
+    {
+        ValidatorModel::notEmpty($args, ['where', 'data']);
+        ValidatorModel::arrayType($args, ['where', 'data']);
+
+        DatabaseModel::delete([
+            'table' => 'tags_entities',
+            'where' => $args['where'],
+            'data'  => $args['data']
+        ]);
+
+        return true;
+    }
+
+    public static function getTagEntities(array $aArgs)
+    {
+        ValidatorModel::arrayType($aArgs, ['select', 'where', 'data', 'orderBy']);
+        ValidatorModel::intType($aArgs, ['limit']);
+
+        $tags = DatabaseModel::select([
+            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
+            'table'     => ['tags_entities'],
+            'where'     => empty($aArgs['where']) ? [] : $aArgs['where'],
+            'data'      => empty($aArgs['data']) ? [] : $aArgs['data'],
+            'order_by'  => empty($aArgs['orderBy']) ? [] : $aArgs['orderBy'],
+            'limit'     => empty($aArgs['limit']) ? 0 : $aArgs['limit']
+        ]);
+
+        return $tags;
+    }
 }
-- 
GitLab