From 34c258d4e502461e4018adabd83ce42fc8273334 Mon Sep 17 00:00:00 2001
From: Damien <damien.burel@maarch.org>
Date: Wed, 9 Jan 2019 15:17:00 +0100
Subject: [PATCH] FIX #8489 Send notes by email

---
 src/app/email/controllers/EmailController.php | 45 +++++++++++++++-
 src/app/entity/models/EntityModelAbstract.php | 10 ++--
 src/app/note/controllers/NoteController.php   | 51 +++++++++++++------
 src/app/note/models/NoteEntityModel.php       | 37 +++++++++++++-
 .../note/models/NoteEntityModelAbstract.php   | 38 --------------
 src/app/note/models/NoteModelAbstract.php     | 20 ++++++++
 .../resource/controllers/StoreController.php  |  2 +-
 .../user/models/UserEntityModelAbstract.php   |  4 +-
 .../controllers/PreparedClauseController.php  |  2 +-
 9 files changed, 143 insertions(+), 66 deletions(-)
 delete mode 100644 src/app/note/models/NoteEntityModelAbstract.php

diff --git a/src/app/email/controllers/EmailController.php b/src/app/email/controllers/EmailController.php
index adc974b028b..f3a49b86c95 100644
--- a/src/app/email/controllers/EmailController.php
+++ b/src/app/email/controllers/EmailController.php
@@ -20,6 +20,9 @@ use Configuration\models\ConfigurationModel;
 use Email\models\EmailModel;
 use Entity\models\EntityModel;
 use Group\models\ServiceModel;
+use Note\controllers\NoteController;
+use Note\models\NoteEntityModel;
+use Note\models\NoteModel;
 use PHPMailer\PHPMailer\PHPMailer;
 use Resource\controllers\ResController;
 use Respect\Validation\Validator;
@@ -88,7 +91,7 @@ class EmailController
 
         $phpmailer = new PHPMailer();
 
-        if ($configuration['type'] == 'smtp') {
+        if ($configuration['type'] == 'smtp') { //TODO TYPE
             $phpmailer->isSMTP();
             $phpmailer->Host = $configuration['host'];
             $phpmailer->Port = $configuration['port'];
@@ -151,7 +154,13 @@ class EmailController
                     }
                 }
             }
-            //TODO NOTES
+            if (!empty($email['document']['notes'])) {
+                $email['document']['notes'] = (array)$email['document']['notes'];
+                $encodedDocument = NoteController::getEncodedPdfByIds(['ids' => $email['document']['notes']]);
+                if (empty($encodedDocument['errors'])) {
+                    $phpmailer->addStringAttachment(base64_decode($encodedDocument['encodedDocument']), 'notes.pdf');
+                }
+            }
         }
 
 
@@ -209,6 +218,38 @@ class EmailController
                     }
                 }
             }
+            if (!empty($args['data']['document']['notes'])) {
+                if (!is_array($args['data']['document']['notes'])) {
+                    return ['errors' => 'Data document[notes] is not an array', 'code' => 400];
+                }
+                foreach ($args['data']['document']['notes'] as $note) {
+                    if (!Validator::intVal()->notEmpty()->validate($note)) {
+                        return ['errors' => 'Data document[notes] errors', 'code' => 400];
+                    }
+                    $checkNote = NoteModel::getById(['id' => $note, 'select' => ['identifier']]);
+                    if (empty($checkNote) || $checkNote['identifier'] != $args['data']['document']['id']) {
+                        return ['errors' => 'Note out of perimeter', 'code' => 403];
+                    }
+
+                    $rawUserEntities = EntityModel::getByLogin(['login' => $args['login'], 'select' => ['entity_id']]);
+                    $userEntities = [];
+                    foreach ($rawUserEntities as $rawUserEntity) {
+                        $userEntities[] = $rawUserEntity['entity_id'];
+                    }
+                    $noteEntities = NoteEntityModel::get(['select' => ['item_id'], 'where' => ['note_id = ?'], 'data' => [$note]]);
+                    if (!empty($noteEntities)) {
+                        $found = false;
+                        foreach ($noteEntities as $noteEntity) {
+                            if (in_array($noteEntity['item_id'], $userEntities)) {
+                                $found = true;
+                            }
+                        }
+                        if (!$found) {
+                            return ['errors' => 'Note out of perimeter', 'code' => 403];
+                        }
+                    }
+                }
+            }
         }
 
         return ['success' => 'success'];
diff --git a/src/app/entity/models/EntityModelAbstract.php b/src/app/entity/models/EntityModelAbstract.php
index b898ecefdfa..9475e1d1825 100755
--- a/src/app/entity/models/EntityModelAbstract.php
+++ b/src/app/entity/models/EntityModelAbstract.php
@@ -178,17 +178,17 @@ abstract class EntityModelAbstract
         return $aReturn;
     }
 
-    public static function getByUserId(array $aArgs)
+    public static function getByLogin(array $aArgs)
     {
-        ValidatorModel::notEmpty($aArgs, ['userId']);
-        ValidatorModel::stringType($aArgs, ['userId']);
+        ValidatorModel::notEmpty($aArgs, ['login']);
+        ValidatorModel::stringType($aArgs, ['login']);
         ValidatorModel::arrayType($aArgs, ['select']);
 
         $aEntities = DatabaseModel::select([
             'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
             'table'     => ['users_entities'],
             'where'     => ['user_id = ?'],
-            'data'      => [$aArgs['userId']]
+            'data'      => [$aArgs['login']]
         ]);
 
         return $aEntities;
@@ -277,7 +277,7 @@ abstract class EntityModelAbstract
             $entitiesAllowedForAdministrator = EntityModel::getAllEntitiesByUserId(['userId' => $aArgs['administratorUserId']]);
         }
 
-        $rawUserEntities = EntityModel::getByUserId(['userId' => $aArgs['userId'], 'select' => ['entity_id']]);
+        $rawUserEntities = EntityModel::getByLogin(['login' => $aArgs['userId'], 'select' => ['entity_id']]);
 
         $userEntities = [];
         foreach ($rawUserEntities as $value) {
diff --git a/src/app/note/controllers/NoteController.php b/src/app/note/controllers/NoteController.php
index db818442330..e2e7d65fb03 100755
--- a/src/app/note/controllers/NoteController.php
+++ b/src/app/note/controllers/NoteController.php
@@ -19,14 +19,17 @@ use Note\models\NoteModel;
 use Note\models\NoteEntityModel;
 use Entity\models\EntityModel;
 use Respect\Validation\Validator;
+use setasign\Fpdi\TcpdfFpdi;
 use Slim\Http\Request;
 use Slim\Http\Response;
 use History\controllers\HistoryController;
 use Resource\controllers\ResController;
+use SrcCore\models\ValidatorModel;
+use User\models\UserModel;
 
 class NoteController
 {
-    public function getByResId(Request $request, Response $response, $aArgs)
+    public function getByResId(Request $request, Response $response, array $aArgs)
     {
         $check = Validator::intVal()->validate($aArgs['resId']);
         if (!$check) {
@@ -38,22 +41,20 @@ class NoteController
         return $response->withJson($aNotes);
     }
 
-    public function create(Request $request, Response $response, $aArgs)
+    public function create(Request $request, Response $response, array $aArgs)
     {
         $data = $request->getParams();
 
-        //Check note text
         $check = Validator::stringType()->notEmpty()->validate($data['note_text']);
-
         if (!$check) {
             return $response->withStatus(400)->withJson(['errors' => 'Bad Request note text']);
         }
         
-        //Check entities chosen
         if (isset($data['entities_chosen'])) {
             
-            $check = $check && Validator::arrayType()->validate($data['entities_chosen']);
-            
+            if (!Validator::arrayType()->validate($data['entities_chosen'])) {
+                return $response->withStatus(400)->withJson(['errors' => 'Bad Request entities chosen']);
+            }
             foreach($data['entities_chosen'] as $entityId) {
 
                 if ($entityId == null) {
@@ -61,12 +62,9 @@ class NoteController
                 }
                 
                 $entity = entitymodel::getByEntityId(['select' => ['id'], 'entityId' => $entityId]);
-
-                $check = $check && Validator::intval()->notEmpty()->validate($entity['id']);
-            }
-
-            if (!$check) {
-                return $response->withStatus(400)->withJson(['errors' => 'Bad Request entities chosen']);
+                if (empty($entity['id'])) {
+                    return $response->withStatus(400)->withJson(['errors' => 'Bad Request entities chosen']);
+                }
             }
         }
 
@@ -76,7 +74,6 @@ class NoteController
         
         $data['identifier'] = $aArgs['resId'];
         
-        //Insert note in notes table and recover last insert ID
         $noteId = NoteModel::create($data);
     
         //Insert relation note with entities in note_entities_table
@@ -86,7 +83,6 @@ class NoteController
             }
         }
 
-        //Insert in history
         HistoryController::add( [
             'tableName' => "notes",
             'recordId'  => $noteId,
@@ -99,4 +95,29 @@ class NoteController
 
         return $response->withJson(['noteId' => $noteId]);
     }
+
+    public static function getEncodedPdfByIds(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['ids']);
+        ValidatorModel::arrayType($aArgs, ['ids']);
+
+        $pdf = new TcpdfFpdi('P', 'pt');
+        $pdf->setPrintHeader(false);
+        $pdf->AddPage();
+
+        foreach ($aArgs['ids'] as $noteId) {
+            $note = NoteModel::getById(['id' => $noteId, 'select' => ['note_text', 'date_note', 'user_id']]);
+
+            $user = UserModel::getByLogin(['login' => $note['user_id'], 'select' => ['firstname', 'lastname']]);
+            $date = new \DateTime($note['date_note']);
+            $date = $date->format('d-m-Y H:i');
+
+            $pdf->Cell(0, 20, "{$user['firstname']} {$user['lastname']} : {$date}", 1, 2, 'C', false);
+            $pdf->MultiCell(0, 20, $note['note_text'] ,1, 'L', false);
+            $pdf->SetY($pdf->GetY() + 40);
+        }
+        $fileContent = $pdf->Output('', 'S');
+
+        return ['encodedDocument' => base64_encode($fileContent)];
+    }
 }
diff --git a/src/app/note/models/NoteEntityModel.php b/src/app/note/models/NoteEntityModel.php
index fe254e095c6..48a7220af19 100644
--- a/src/app/note/models/NoteEntityModel.php
+++ b/src/app/note/models/NoteEntityModel.php
@@ -8,12 +8,45 @@
  */
 
 /**
- * @brief Note Model
+ * @brief Note Entity Model
  * @author dev@maarch.org
  */
 
 namespace Note\models;
 
-class NoteEntityModel extends NoteEntityModelAbstract
+use SrcCore\models\DatabaseModel;
+use SrcCore\models\ValidatorModel;
+
+class NoteEntityModel
 {
+    public static function get(array $aArgs = [])
+    {
+        ValidatorModel::arrayType($aArgs, ['select', 'where', 'data']);
+
+        $noteEntities = DatabaseModel::select([
+            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
+            'table'     => ['note_entities'],
+            'where'     => empty($aArgs['where']) ? [] : $aArgs['where'],
+            'data'      => empty($aArgs['data']) ? [] : $aArgs['data']
+        ]);
+
+        return $noteEntities;
+    }
+
+    public static function create(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['note_id', 'item_id']);
+        ValidatorModel::intVal($aArgs, ['note_id']);
+        ValidatorModel::stringType($aArgs, ['item_id']);
+
+        DatabaseModel::insert([
+            'table' => 'note_entities',
+            'columnsValues' => [
+                'note_id'   => $aArgs['note_id'],
+                'item_id'   => $aArgs['item_id']
+            ]
+        ]);
+
+        return true;
+    }
 }
\ No newline at end of file
diff --git a/src/app/note/models/NoteEntityModelAbstract.php b/src/app/note/models/NoteEntityModelAbstract.php
deleted file mode 100644
index 57ab1be4130..00000000000
--- a/src/app/note/models/NoteEntityModelAbstract.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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 Note Model
- * @author dev@maarch.org
- */
-
-namespace Note\models;
-
-use SrcCore\models\DatabaseModel;
-use SrcCore\models\ValidatorModel;
-
-abstract class NoteEntityModelAbstract
-{
-    public static function create(array $aArgs)
-    {
-        ValidatorModel::notEmpty($aArgs, ['note_id', 'item_id']);
-        ValidatorModel::intVal($aArgs, ['note_id']);
-        ValidatorModel::stringType($aArgs, ['item_id']);
-
-        DatabaseModel::insert([
-            'table' => 'note_entities',
-            'columnsValues' => [
-                'note_id'   => $aArgs['note_id'],
-                'item_id'   => $aArgs['item_id']
-            ]
-        ]);
-
-        return true;
-    }
-}
diff --git a/src/app/note/models/NoteModelAbstract.php b/src/app/note/models/NoteModelAbstract.php
index 0dee049b8d5..7857d8ae240 100755
--- a/src/app/note/models/NoteModelAbstract.php
+++ b/src/app/note/models/NoteModelAbstract.php
@@ -19,6 +19,26 @@ use SrcCore\models\ValidatorModel;
 
 abstract class NoteModelAbstract
 {
+    public static function getById(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['id']);
+        ValidatorModel::intVal($aArgs, ['id']);
+        ValidatorModel::arrayType($aArgs, ['select']);
+
+        $note = DatabaseModel::select([
+            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
+            'table'     => ['notes'],
+            'where'     => ['id = ?'],
+            'data'      => [$aArgs['id']],
+        ]);
+
+        if (empty($note[0])) {
+            return [];
+        }
+
+        return $note[0];
+    }
+
     public static function countByResId(array $aArgs)
     {
         ValidatorModel::notEmpty($aArgs, ['resId', 'login']);
diff --git a/src/app/resource/controllers/StoreController.php b/src/app/resource/controllers/StoreController.php
index 366f7a554cc..17e436bdb1e 100755
--- a/src/app/resource/controllers/StoreController.php
+++ b/src/app/resource/controllers/StoreController.php
@@ -269,7 +269,7 @@ class StoreController
                 if (!empty($user[0]['user_id'])) {
                     $toAddressFound = true;
                     $destUser = $user[0]['user_id'];
-                    $entity = EntityModel::getByUserId(['userId' => $destUser, 'select' => ['entity_id']]);
+                    $entity = EntityModel::getByLogin(['login' => $destUser, 'select' => ['entity_id']]);
                     if (!empty($entity[0]['entity_id'])) {
                         $userEntity = $entity[0]['entity_id'];
                         $userPrimaryEntity = true;
diff --git a/src/app/user/models/UserEntityModelAbstract.php b/src/app/user/models/UserEntityModelAbstract.php
index 05fc09d3fec..14aaad5217b 100755
--- a/src/app/user/models/UserEntityModelAbstract.php
+++ b/src/app/user/models/UserEntityModelAbstract.php
@@ -126,7 +126,7 @@ abstract class UserEntityModelAbstract
         ValidatorModel::stringType($aArgs, ['entityId']);
 
         $user = UserModel::getById(['id' => $aArgs['id'], 'select' => ['user_id']]);
-        $entities = EntityModel::getByUserId(['userId' => $user['user_id']]);
+        $entities = EntityModel::getByLogin(['login' => $user['user_id']]);
         foreach ($entities as $entity) {
             if ($entity['primary_entity'] == 'Y') {
                 DatabaseModel::update([
@@ -157,7 +157,7 @@ abstract class UserEntityModelAbstract
         ValidatorModel::notEmpty($aArgs, ['userId']);
         ValidatorModel::stringType($aArgs, ['userId']);
 
-        $entities = EntityModel::getByUserId(['userId' => $aArgs['userId']]);
+        $entities = EntityModel::getByLogin(['login' => $aArgs['userId']]);
         if (!empty($entities[0])) {
             DatabaseModel::update([
                 'table'     => 'users_entities',
diff --git a/src/core/controllers/PreparedClauseController.php b/src/core/controllers/PreparedClauseController.php
index 3339cbcd219..ad6f9d1342f 100755
--- a/src/core/controllers/PreparedClauseController.php
+++ b/src/core/controllers/PreparedClauseController.php
@@ -36,7 +36,7 @@ class PreparedClauseController
             $clause = str_replace('@email', "'{$user['mail']}'", $clause);
         }
         if (preg_match('/@my_entities/', $clause)) {
-            $entities = EntityModel::getByUserId(['userId' => $aArgs['login'], 'select' => ['entity_id']]);
+            $entities = EntityModel::getByLogin(['login' => $aArgs['login'], 'select' => ['entity_id']]);
 
             $myEntitiesClause = '';
             foreach ($entities as $key => $entity) {
-- 
GitLab