Skip to content
Snippets Groups Projects
TileController.php 13 KiB
Newer Older
  • Learn to ignore specific revisions
  • <?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 Tile Controller
     * @author dev@maarch.org
     */
    
    namespace Home\controllers;
    
    
    use Basket\models\BasketModel;
    
    use Contact\controllers\ContactController;
    
    use Doctype\models\DoctypeModel;
    use Group\models\GroupModel;
    
    use History\controllers\HistoryController;
    use Home\models\TileModel;
    
    use Resource\models\ResModel;
    
    use Respect\Validation\Validator;
    use Slim\Http\Request;
    use Slim\Http\Response;
    
    use SrcCore\controllers\PreparedClauseController;
    
    use Status\models\StatusModel;
    
    use User\models\UserModel;
    
    
    class TileController
    {
    
        const TYPES = ['myLastResources', 'basket', 'searchTemplate', 'followedMail', 'folder', 'externalSignatoryBook', 'shortcut'];
    
        const VIEWS = ['list', 'resume', 'chart'];
    
        public function get(Request $request, Response $response)
        {
            $tiles = TileModel::get([
                'select'    => ['*'],
                'where'     => ['user_id = ?'],
                'data'      => [$GLOBALS['id']]
            ]);
    
    
            foreach ($tiles as $key => $tile) {
    
                $tiles[$key]['parameters'] = json_decode($tile['parameters'], true);
    
                TileController::getShortDetails($tiles[$key]);
    
            return $response->withJson(['tiles' => $tiles]);
        }
    
    
        public function getById(Request $request, Response $response, array $args)
        {
            $tile = TileModel::getById([
                'select'    => ['*'],
    
    Damien's avatar
    Damien committed
                'id'        => $args['id']
    
            ]);
            if (empty($tile) || $tile['user_id'] != $GLOBALS['id']) {
                return $response->withStatus(400)->withJson(['errors' => 'Tile out of perimeter']);
            }
    
            $tile['parameters'] = json_decode($tile['parameters'], true);
    
            $control = TileController::getDetails($tile);
            if (!empty($control['errors'])) {
                return $response->withStatus(400)->withJson(['errors' => $control['errors']]);
            }
    
            return $response->withJson(['tile' => $tile]);
        }
    
    
        public function create(Request $request, Response $response)
        {
            $body = $request->getParsedBody();
    
            if (empty($body)) {
                return $response->withStatus(400)->withJson(['errors' => 'Body is empty']);
            } elseif (!Validator::stringType()->notEmpty()->validate($body['type'] ?? null) || !in_array($body['type'], TileController::TYPES)) {
                return $response->withStatus(400)->withJson(['errors' => 'Body type is empty, not a string or not valid']);
            } elseif (!Validator::stringType()->notEmpty()->validate($body['view'] ?? null) || !in_array($body['view'], TileController::VIEWS)) {
                return $response->withStatus(400)->withJson(['errors' => 'Body view is empty, not a string or not valid']);
    
            } elseif (!Validator::intVal()->validate($body['position'] ?? null)) {
                return $response->withStatus(400)->withJson(['errors' => 'Body position is not set or not an integer']);
    
            }
    
            $tiles = TileModel::get([
                'select'    => [1],
                'where'     => ['user_id = ?'],
                'data'      => [$GLOBALS['id']]
            ]);
            if (count($tiles) >= 6) {
                return $response->withStatus(400)->withJson(['errors' => 'Too many tiles (limited to 6)']);
            }
    
            $control = TileController::controlParameters($body);
            if (!empty($control['errors'])) {
                return $response->withStatus(400)->withJson(['errors' => $control['errors']]);
            }
    
    
            $id = TileModel::create([
                'user_id'       => $GLOBALS['id'],
                'type'          => $body['type'],
                'view'          => $body['view'],
                'position'      => $body['position'],
                'parameters'    => empty($body['parameters']) ? '{}' : json_encode($body['parameters'])
            ]);
    
            HistoryController::add([
                'tableName'    => 'tiles',
    
                'eventType'    => 'ADD',
                'eventId'      => 'tileCreation',
                'info'         => 'tile creation'
            ]);
    
            return $response->withJson(['id' => $id]);
        }
    
    
        public function update(Request $request, Response $response, array $args)
        {
            $tile = TileModel::getById(['select' => ['user_id'], 'id' => $args['id']]);
            if (empty($tile) || $tile['user_id'] != $GLOBALS['id']) {
                return $response->withStatus(400)->withJson(['errors' => 'Tile out of perimeter']);
            }
    
            $body = $request->getParsedBody();
    
            if (empty($body)) {
                return $response->withStatus(400)->withJson(['errors' => 'Body is empty']);
            } elseif (!Validator::stringType()->notEmpty()->validate($body['view'] ?? null) || !in_array($body['view'], TileController::VIEWS)) {
                return $response->withStatus(400)->withJson(['errors' => 'Body view is empty, not a string or not valid']);
            }
    
            TileModel::update([
                'set'   => [
                    'view'          => $body['view'],
                    'parameters'    => empty($body['parameters']) ? '{}' : json_encode($body['parameters'])
                ],
                'where' => ['id = ?'],
                'data'  => [$args['id']]
            ]);
    
            HistoryController::add([
                'tableName'    => 'tiles',
                'recordId'     => $args['id'],
                'eventType'    => 'UP',
                'eventId'      => 'tileModification',
                'info'         => 'tile modification'
            ]);
    
            return $response->withStatus(204);
        }
    
        public function delete(Request $request, Response $response, array $args)
        {
            $tile = TileModel::getById(['select' => ['user_id'], 'id' => $args['id']]);
            if (empty($tile) || $tile['user_id'] != $GLOBALS['id']) {
                return $response->withStatus(400)->withJson(['errors' => 'Tile out of perimeter']);
            }
    
            TileModel::delete([
                'where' => ['id = ?'],
                'data'  => [$args['id']]
            ]);
    
            HistoryController::add([
                'tableName'    => 'tiles',
                'recordId'     => $args['id'],
                'eventType'    => 'DEL',
                'eventId'      => 'tileSuppression',
                'info'         => 'tile suppression'
            ]);
    
            return $response->withStatus(204);
        }
    
        public function updatePositions(Request $request, Response $response)
        {
            $body = $request->getParsedBody();
    
            if (empty($body)) {
                return $response->withStatus(400)->withJson(['errors' => 'Body is empty']);
            } elseif (!Validator::arrayType()->notEmpty()->validate($body['tiles'] ?? null)) {
                return $response->withStatus(400)->withJson(['errors' => 'Body tiles is empty not not an array']);
            }
    
            $userTiles = TileModel::get(['select' => ['id'], 'where' => ['user_id = ?'], 'data' => [$GLOBALS['id']]]);
            if (count($userTiles) != count($body['tiles'])) {
                return $response->withStatus(400)->withJson(['errors' => 'Body tiles do not match user tiles']);
            }
            $allTiles = array_column($userTiles, 'id');
            foreach ($body['tiles'] as $tile) {
                if (!in_array($tile['id'], $allTiles)) {
                    return $response->withStatus(400)->withJson(['errors' => 'Tiles out of perimeter']);
                }
            }
    
            foreach ($body['tiles'] as $key => $tile) {
    
                TileModel::update([
                    'set'   => [
                        'position' => $tile['position'],
                    ],
                    'where' => ['id = ?'],
                    'data'  => [$tile['id']]
                ]);
    
    
        private static function controlParameters(array $args)
        {
            if ($args['type'] == 'basket') {
                if (!Validator::arrayType()->notEmpty()->validate($args['parameters'] ?? null)) {
                    return ['errors' => 'Body parameters is empty or not an array'];
                } elseif (!Validator::intVal()->validate($args['parameters']['basketId'] ?? null)) {
                    return ['errors' => 'Body[parameters] basketId is empty or not an integer'];
                } elseif (!Validator::intVal()->validate($args['parameters']['groupId'] ?? null)) {
                    return ['errors' => 'Body[parameters] groupId is empty or not an integer'];
                }
    
                $basket = BasketModel::getById(['select' => ['basket_id'], 'id' => $args['parameters']['basketId']]);
                $group = GroupModel::getById(['select' => ['group_id'], 'id' => $args['parameters']['groupId']]);
                if (empty($basket) || empty($group)) {
                    return ['errors' => 'Basket or group do not exist'];
                } elseif (!BasketModel::hasGroup(['id' => $basket['basket_id'], 'groupId' => $group['group_id']])) {
    
                    return ['errors' => 'Basket is not linked to this group'];
    
                } elseif (!UserModel::hasGroup(['id' => $GLOBALS['id'], 'groupId' => $group['group_id']])) {
    
                    return ['errors' => 'User is not linked to this group'];
                }
            }
    
            return true;
        }
    
    
        private static function getShortDetails(array &$tile)
    
        {
            if ($tile['type'] == 'basket') {
    
                $basket = BasketModel::getById(['select' => ['basket_clause', 'basket_name', 'basket_id'], 'id' => $tile['parameters']['basketId']]);
                $group = GroupModel::getById(['select' => ['group_desc', 'group_id'], 'id' => $tile['parameters']['groupId']]);
    
                $tile['basketName'] = $basket['basket_name'];
                $tile['groupName'] = $group['group_desc'];
            }
    
            return true;
        }
    
        private static function getDetails(array &$tile)
        {
            if ($tile['type'] == 'basket') {
                $basket = BasketModel::getById(['select' => ['basket_clause', 'basket_id'], 'id' => $tile['parameters']['basketId']]);
                $group = GroupModel::getById(['select' => ['group_id'], 'id' => $tile['parameters']['groupId']]);
    
                if (!BasketModel::hasGroup(['id' => $basket['basket_id'], 'groupId' => $group['group_id']])) {
    
                    return ['errors' => 'Basket is not linked to this group'];
    
                } elseif (!UserModel::hasGroup(['id' => $GLOBALS['id'], 'groupId' => $group['group_id']])) {
    
                    return ['errors' => 'User is not linked to this group'];
                }
    
                if ($tile['view'] == 'resume') {
    
    Damien's avatar
    Damien committed
                    $tile['resourcesNumber'] = BasketModel::getResourceNumberByClause(['userId' => $GLOBALS['id'], 'clause' => $basket['basket_clause']]);
    
                } elseif ($tile['view'] == 'list') {
    
                    $resources = ResModel::getOnView([
                        'select'    => ['subject', 'creation_date', 'res_id'],
                        'where'     => [PreparedClauseController::getPreparedClause(['userId' => $GLOBALS['id'], 'clause' => $basket['basket_clause']])],
                        'orderBy'   => ['creation_date'],
                        'limit'     => 10
                    ]);
                    $tile['resources'] = [];
                    foreach ($resources as $resource) {
                        $senders = ContactController::getFormattedContacts(['resId' => $resource['res_id'], 'mode' => 'sender', 'onlyContact' => true]);
                        $recipients = ContactController::getFormattedContacts(['resId' => $resource['res_id'], 'mode' => 'recipient', 'onlyContact' => true]);
    
                        $tile['resources'][] = [
                            'resId'         => $resource['res_id'],
                            'subject'       => $resource['subject'],
                            'creationDate'  => $resource['creation_date'],
                            'senders'       => $senders ,
                            'recipients'    => $recipients
                        ];
                    }
    
                } elseif ($tile['view'] == 'chart') {
    
                    if (!empty($tile['parameters']['chartMode']) && $tile['parameters']['chartMode'] == 'status') {
                        $type = 'status';
                    } else {
                        $type = 'type_id';
                    }
    
                    $resources = ResModel::getOnView([
    
                        'select'    => ["COUNT({$type})", $type],
    
                        'where'     => [PreparedClauseController::getPreparedClause(['userId' => $GLOBALS['id'], 'clause' => $basket['basket_clause']])],
    
                        'groupBy'   => [$type]
    
                    ]);
                    $tile['resources'] = [];
                    foreach ($resources as $resource) {
    
                        if ($type == 'status') {
                            $status['label_status'] = null;
                            if (!empty($resource['status'])) {
                                $status = StatusModel::getById(['select' => ['label_status'], 'id' => $resource['status']]);
                            }
                            $tile['resources'][] = ['name' => $status['label_status'], 'value' => $resource['count']];
                        } else {
                            $doctype = DoctypeModel::getById(['select' => ['description'], 'id' => $resource['type_id']]);
                            $tile['resources'][] = ['name' => $doctype['description'], 'value' => $resource['count']];
                        }