Skip to content
Snippets Groups Projects
AutoCompleteController.php 14.2 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 Auto Complete Controller
    * @author dev@maarch.org
    */
    
    namespace SrcCore\controllers;
    
    
    Damien's avatar
    Damien committed
    use Contact\controllers\ContactGroupController;
    
    Damien's avatar
    Damien committed
    use Contact\models\ContactModel;
    
    Damien's avatar
    Damien committed
    use Respect\Validation\Validator;
    
    use Slim\Http\Request;
    use Slim\Http\Response;
    use Entity\models\EntityModel;
    
    use SrcCore\models\CoreConfigModel;
    
    use SrcCore\models\DatabaseModel;
    
    Damien's avatar
    Damien committed
    use SrcCore\models\TextFormatModel;
    
    use SrcCore\models\ValidatorModel;
    
    use Status\models\StatusModel;
    use User\models\UserModel;
    
    class AutoCompleteController
    {
    
    Damien's avatar
    Damien committed
        public static function getContacts(Request $request, Response $response)
        {
            $data = $request->getQueryParams();
    
            $check = Validator::stringType()->notEmpty()->validate($data['search']);
            $check = $check && Validator::stringType()->notEmpty()->validate($data['type']);
            if (!$check) {
                return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
            }
    
            $searchItems = explode(' ', $data['search']);
    
            $fields = '(contact_firstname ilike ? OR contact_lastname ilike ? OR firstname ilike ? OR lastname ilike ? OR society ilike ? 
                        OR address_num ilike ? OR address_street ilike ? OR address_town ilike ? OR address_postal_code ilike ?)';
    
    Damien's avatar
    Damien committed
            $where = [];
            $requestData = [];
            if ($data['type'] != 'all') {
                $where = ['contact_type = ?'];
                $requestData = [$data['type']];
            }
    
    Damien's avatar
    Damien committed
            foreach ($searchItems as $item) {
    
    Damien's avatar
    Damien committed
                if (strlen($item) >= 2) {
                    $where[] = $fields;
                    for ($i = 0; $i < 9; $i++) {
    
    Damien's avatar
    Damien committed
                        $requestData[] = "%{$item}%";
    
    Damien's avatar
    Damien committed
                }
            }
    
            $contacts = ContactModel::getOnView([
                'select'    => [
                    'ca_id', 'firstname', 'lastname', 'contact_lastname', 'contact_firstname', 'society', 'address_num',
                    'address_street', 'address_town', 'address_postal_code', 'is_corporate_person'
                ],
                'where'     => $where,
    
    Damien's avatar
    Damien committed
                'data'      => $requestData,
    
    Damien's avatar
    Damien committed
                'limit'     => 1000
    
    Damien's avatar
    Damien committed
            ]);
    
            $data = [];
            foreach ($contacts as $contact) {
    
    Florian Azizian's avatar
    Florian Azizian committed
                $data[] = ContactGroupController::getFormattedContact(['contact' => $contact])['contact'];
    
    Damien's avatar
    Damien committed
            }
    
            return $response->withJson($data);
        }
    
    
        public static function getUsers(Request $request, Response $response)
        {
    
            $data = $request->getQueryParams();
    
            $check = Validator::stringType()->notEmpty()->validate($data['search']);
            if (!$check) {
                return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
            }
    
            $excludedUsers = ['superadmin'];
    
    
            $requestData = AutoCompleteController::getDataForRequest([
                'search'        => $data['search'],
                'fields'        => '(firstname ilike ? OR lastname ilike ?)',
                'where'         => ['enabled = ?', 'status != ?', 'user_id not in (?)'],
                'data'          => ['Y', 'DEL', $excludedUsers],
                'fieldsNumber'  => 2,
            ]);
    
            $users = UserModel::get([
                'select'    => ['user_id', 'firstname', 'lastname'],
    
                'where'     => $requestData['where'],
                'data'      => $requestData['data'],
    
                'orderBy'   => ['lastname']
            ]);
    
    
            $data = [];
    
    Florian Azizian's avatar
    Florian Azizian committed
            foreach ($users as $value) {
    
                $data[] = [
                    'type'          => 'user',
                    'id'            => $value['user_id'],
                    'idToDisplay'   => "{$value['firstname']} {$value['lastname']}",
    
                    'otherInfo'     => ''
    
                ];
            }
    
            return $response->withJson($data);
        }
    
    
        public static function getUsersForAdministration(Request $request, Response $response)
        {
    
            $data = $request->getQueryParams();
            $check = Validator::stringType()->notEmpty()->validate($data['search']);
            if (!$check) {
                return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
            }
    
            $excludedUsers = ['superadmin'];
    
    
            if ($GLOBALS['userId'] != 'superadmin') {
                $entities = EntityModel::getAllEntitiesByUserId(['userId' => $GLOBALS['userId']]);
    
    
                $requestData = AutoCompleteController::getDataForRequest([
                    'search'        => $data['search'],
                    'fields'        => '(users.firstname ilike ? OR users.lastname ilike ?)',
                    'where'         => [
                        'users.user_id = users_entities.user_id',
                        'users_entities.entity_id in (?)',
                        'users.status != ?',
                        'users.enabled = ?'
                    ],
                    'data'          => [$entities, 'DEL', 'Y'],
                    'fieldsNumber'  => 2,
                ]);
    
                $users = DatabaseModel::select([
    
    Damien's avatar
    Damien committed
                    'select'    => ['DISTINCT users.user_id', 'users.id', 'users.firstname', 'users.lastname'],
    
                    'table'     => ['users, users_entities'],
                    'where'     => $requestData['where'],
                    'data'      => $requestData['data']
                ]);
    
                $requestData = AutoCompleteController::getDataForRequest([
                    'search'        => $data['search'],
                    'fields'        => '(users.firstname ilike ? OR users.lastname ilike ?)',
                    'where'         => [
                        'users_entities IS NULL',
                        'users.user_id not in (?)',
                        'users.status != ?',
                        'users.enabled = ?'
                    ],
                    'data'          => [$excludedUsers, 'DEL', 'Y'],
                    'fieldsNumber'  => 2,
    
    
                $usersNoEntities = DatabaseModel::select([
                    'select'    => ['users.id', 'users.user_id', 'users.firstname', 'users.lastname'],
                    'table'     => ['users', 'users_entities'],
                    'left_join' => ['users.user_id = users_entities.user_id'],
                    'where'     => $requestData['where'],
                    'data'      => $requestData['data']
                ]);
    
    
                $users = array_merge($users, $usersNoEntities);
            } else {
    
                $requestData = AutoCompleteController::getDataForRequest([
                    'search'        => $data['search'],
                    'fields'        => '(firstname ilike ? OR lastname ilike ?)',
                    'where'         => ['enabled = ?', 'status != ?', 'user_id not in (?)'],
                    'data'          => ['Y', 'DEL', $excludedUsers],
                    'fieldsNumber'  => 2,
                ]);
    
    
                $users = UserModel::get([
    
                    'select'    => ['user_id', 'firstname', 'lastname'],
                    'where'     => $requestData['where'],
                    'data'      => $requestData['data'],
    
                    'orderBy'   => ['lastname']
                ]);
            }
    
            $data = [];
    
    Florian Azizian's avatar
    Florian Azizian committed
            foreach ($users as $value) {
    
                $data[] = [
                    'type'          => 'user',
    
                    'id'            => $value['id'],
                    'idToDisplay'   => "{$value['firstname']} {$value['lastname']}",
                    'otherInfo'     => $value['user_id']
    
                ];
            }
    
            return $response->withJson($data);
        }
    
    
        public static function getUsersForVisa(Request $request, Response $response)
        {
    
            $data = $request->getQueryParams();
            $check = Validator::stringType()->notEmpty()->validate($data['search']);
            if (!$check) {
                return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
            }
    
    
            $excludedUsers = ['superadmin'];
    
    
            $requestData = AutoCompleteController::getDataForRequest([
                'search'        => $data['search'],
                'fields'        => '(users.firstname ilike ? OR users.lastname ilike ?)',
                'where'         => [
    
                    'usergroup_content.group_id = usergroups_services.group_id',
                    'usergroup_content.user_id = users.user_id',
                    'usergroups_services.service_id in (?)',
                    'users.user_id not in (?)',
                    'users.enabled = ?',
                    'users.status != ?'
                ],
    
                'data'          => [['visa_documents', 'sign_document'], $excludedUsers, 'Y', 'DEL'],
                'fieldsNumber'  => 2,
            ]);
    
            $users = DatabaseModel::select([
                'select'    => ['DISTINCT users.user_id', 'users.firstname', 'users.lastname'],
                'table'     => ['users, usergroup_content, usergroups_services'],
                'where'     => $requestData['where'],
                'data'      => $requestData['data'],
    
                'order_by'  => ['users.lastname']
    
            ]);
    
            $data = [];
    
            foreach ($users as $key => $value) {
                $data[] = [
                    'type'          => 'user',
                    'id'            => $value['user_id'],
                    'idToDisplay'   => "{$value['firstname']} {$value['lastname']}",
                    'otherInfo'     => ''
                ];
    
            }
    
            return $response->withJson($data);
        }
    
        public static function getEntities(Request $request, Response $response)
        {
    
            $data = $request->getQueryParams();
            $check = Validator::stringType()->notEmpty()->validate($data['search']);
            if (!$check) {
                return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
            }
    
            $requestData = AutoCompleteController::getDataForRequest([
                'search'        => $data['search'],
                'fields'        => '(entity_label ilike ?)',
                'where'         => ['enabled = ?'],
                'data'          => ['Y'],
                'fieldsNumber'  => 1,
            ]);
    
    
            $entities = EntityModel::get([
                'select'    => ['entity_id', 'entity_label', 'short_label'],
    
                'where'     => $requestData['where'],
                'data'      => $requestData['data'],
    
                'orderBy'   => ['entity_label']
            ]);
    
            $data = [];
    
    Florian Azizian's avatar
    Florian Azizian committed
            foreach ($entities as $value) {
    
                $data[] = [
                    'type'          => 'entity',
                    'id'            => $value['entity_id'],
                    'idToDisplay'   => $value['entity_label'],
                    'otherInfo'     => $value['short_label']
                ];
            }
    
            return $response->withJson($data);
        }
    
        public static function getStatuses(Request $request, Response $response)
        {
    
            $statuses = StatusModel::get(['select' => ['id', 'label_status', 'img_filename']]);
    
    
            $data = [];
    
    Florian Azizian's avatar
    Florian Azizian committed
            foreach ($statuses as $value) {
    
                $data[] = [
                    'type'          => 'status',
                    'id'            => $value['id'],
                    'idToDisplay'   => $value['label_status'],
    
                    'otherInfo'     => $value['img_filename']
    
                ];
            }
    
            return $response->withJson($data);
        }
    
    Damien's avatar
    Damien committed
    
        public static function getBanAddresses(Request $request, Response $response)
        {
            $data = $request->getQueryParams();
    
            $check = Validator::stringType()->notEmpty()->validate($data['address']);
    
    Damien's avatar
    Damien committed
            $check = $check && Validator::stringType()->notEmpty()->validate($data['department']);
    
    Damien's avatar
    Damien committed
            if (!$check) {
                return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
            }
    
            $customId = CoreConfigModel::getCustomId();
    
            if (is_dir("custom/{$customId}/referential/ban/indexes/{$data['department']}")) {
                $path = "custom/{$customId}/referential/ban/indexes/{$data['department']}";
            } elseif (is_dir('referential/ban/indexes/' . $data['department'])) {
                $path = 'referential/ban/indexes/' . $data['department'];
            } else {
    
    Damien's avatar
    Damien committed
                return $response->withStatus(400)->withJson(['errors' => 'Department indexes do not exist']);
            }
    
    Damien's avatar
    Damien committed
    
            \Zend_Search_Lucene_Analysis_Analyzer::setDefault(new \Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive());
            \Zend_Search_Lucene_Search_QueryParser::setDefaultOperator(\Zend_Search_Lucene_Search_QueryParser::B_AND);
            \Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding('utf-8');
    
    
            $index = \Zend_Search_Lucene::open($path);
    
    Damien's avatar
    Damien committed
            \Zend_Search_Lucene::setResultSetLimit(100);
    
            $data['address'] = str_replace(['*', '~', '-', '\''], ' ', $data['address']);
            $aAddress = explode(' ', $data['address']);
            foreach ($aAddress as $key => $value) {
    
    Damien's avatar
    Damien committed
                if (strlen($value) <= 2 && !is_numeric($value)) {
    
    Damien's avatar
    Damien committed
                    unset($aAddress[$key]);
                    continue;
                }
                if (strlen($value) >= 3 && $value != 'rue' && $value != 'avenue' && $value != 'boulevard') {
                    $aAddress[$key] .= '*';
                }
            }
            $data['address'] = implode(' ', $aAddress);
    
            if (empty($data['address'])) {
                return $response->withJson([]);
            }
    
    Damien's avatar
    Damien committed
    
            $hits = $index->find(TextFormatModel::normalize(['string' => $data['address']]));
    
    Damien's avatar
    Damien committed
    
    
    Damien's avatar
    Damien committed
            $addresses = [];
    
    Florian Azizian's avatar
    Florian Azizian committed
            foreach ($hits as $key => $hit) {
    
    Damien's avatar
    Damien committed
                $addresses[] = [
    
    Damien's avatar
    Damien committed
                    'banId'         => $hit->banId,
                    'number'        => $hit->streetNumber,
                    'afnorName'     => $hit->afnorName,
                    'postalCode'    => $hit->postalCode,
    
    Damien's avatar
    Damien committed
                    'city'          => $hit->city,
                    'address'       => "{$hit->streetNumber} {$hit->afnorName}, {$hit->city} ({$hit->postalCode})"
    
    Damien's avatar
    Damien committed
            return $response->withJson($addresses);
    
    Damien's avatar
    Damien committed
        }
    
    
        private static function getDataForRequest(array $aArgs)
        {
            ValidatorModel::notEmpty($aArgs, ['search', 'fields', 'where', 'data', 'fieldsNumber']);
            ValidatorModel::stringType($aArgs, ['search', 'fields']);
            ValidatorModel::arrayType($aArgs, ['where', 'data']);
            ValidatorModel::intType($aArgs, ['fieldsNumber']);
    
            $searchItems = explode(' ', $aArgs['search']);
    
            foreach ($searchItems as $item) {
                if (strlen($item) >= 2) {
                    $aArgs['where'][] = $aArgs['fields'];
                    for ($i = 0; $i < $aArgs['fieldsNumber']; $i++) {
                        $aArgs['data'][] = "%{$item}%";
                    }
                }
            }
    
            return ['where' => $aArgs['where'], 'data' => $aArgs['data']];
        }