Untitled

 avatar
user_3839718
php
a year ago
18 kB
1
Indexable
Never
<?php

namespace App\Model;

use Laminas\Db\Adapter\AdapterInterface;
use Laminas\ServiceManager\ServiceManager;
use Laminas\Mail\Transport\TransportInterface;
use App\Model\User;
use App\Helper\QueryBuilder;
use Laminas\Db\Sql\Select;


abstract class AbstractBaseManager
{
    protected $config;
    protected $dbAdapter;
    protected $tableGateways = [];
    private $viewConfig = [
        'user' => [
            'id' => 'id',
            'email' => 'email',
            'fullName' => 'fullname',
            'nickName' => 'short_name',
            'companyName' => 'company_name',
            'mobile' => 'mobile',
            'legalName' => 'legal_name',
            'dateCreated' => 'date_created',
            'status' => 'status',
            'country' => 'country',
            'timeZone' => 'time_zone',
            'language' => 'language',
            'address' => 'address',
            'canWrite' => '',
            'canRead' => ''
        ],
        'robot' => ['name' => 'robot_name', 'id' => 'id', 'status' => 'status', 'dateCreated' => 'date_created', 'masterToken' => 'master_token'],
        'farm' => [
            'id' => 'id',
            'name' => 'name',
            'nickName' => 'nick_name',
            'address' => 'address',
            'country' => 'country_id',
            'status' => 'status',
            'gps' => 'gps',
            'description' => 'description',
            'dateCreated' => 'date_created'
        ],
        'round' => [
            'id' => 'id',
            'from' => 'from',
            'to' => 'to',
            'species' => 'species_id',
            'targetMortality' => 'target_mortality',
            'exportable' => 'exportable',
            'gender' => 'gender',
            'finalExits' => 'final_exits',
            'status' => 'status',
            'initialEntry' => 'initial_entries',
            'comments' => 'comments'
        ],
        'house' => [
            'id' => 'id',
            'name' => 'name',
            'nickName' => 'nick_name',
            'gps' => 'gps',
            'status' => 'status',
            'description' => 'description',
            'dateCreated' => 'date_created',
            'growthCurve' => 'growth_curve',
            'temperatureCurve' => 'temperature_curve'
        ],
        'alert' => [
            'id' => 'id',
            'notificationMethod' => 'notification_method_id',
            'subject' => 'subject',
            'message' => 'message',
            'level' => 'level',
            'time' => 'time',
            'date' => 'date_created'
        ],
        'diary' => ['id' => 'id', 'note' => 'note', 'date' => 'date_created'],
        'climate_controller' => ['climateType' => 'name_ld'],
        'climate' => ['climateController' => 'name'],
        'house_type' => ['houseType' => 'name_ld'],
    ];

    //Confirm if this config is needed
    private $viewConfigAdmin = [
        'user' => [
            'id' => 'id',
            'email' => 'email',
            'fullName' => 'fullname',
            'nickName' => 'short_name',
            'companyName' => 'company_name',
            'mobile' => 'mobile',
            'legalName' => 'legal_name',
            'dateCreated' => 'date_created',
            'status' => 'status',
            'country' => 'country',
            'timeZone' => 'time_zone',
            'language' => 'language',
            'address' => 'address',
            'canWrite' => '',
            'canRead' => ''
        ],
        'robot' => ['name' => 'robot_name', 'id' => 'id', 'status' => 'status', 'dateCreated' => 'date_created', 'masterToken' => 'master_token'],
        'farm' => [
            'id' => 'id',
            'name' => 'name',
            'nickName' => 'nick_name',
            'address' => 'address',
            'country' => 'country_id',
            'status' => 'status',
            'gps' => 'gps',
            'description' => 'description',
            'dateCreated' => 'date_created'
        ],
        'round' => [
            'id' => 'id',
            'house_id' => 'house_id',
            'from' => 'from',
            'to' => 'to',
            'species' => 'species_id',
            'targetMortality' => 'target_mortality',
            'finalExits' => 'final_exits',
            'status' => 'status',
            'initialEntry' => 'initial_entries',
            'comments' => 'comments'
        ],
        'house' => [
            'id' => 'id',
            'name' => 'name',
            'nickName' => 'nick_name',
            'gps' => 'gps',
            'status' => 'status',
            'description' => 'description',
            'dateCreated' => 'date_created',
            'growthCurve' => 'growth_curve',
            'temperatureCurve' => 'temperature_curve'
        ],
        'alert_notification' => [
            'id' => 'id',
            'notificationMethod' => 'notification_method_id',
            'subject' => 'subject',
            'message' => 'message',
            'level' => 'level',
            'time' => 'time',
            'date' => 'date_created'
        ],
        'diary' => ['id' => 'id', 'note' => 'note', 'date' => 'date_created'],
        'climate_controller' => ['climateType' => 'name_ld'],
        'climate' => ['climateController' => 'name'],
        'house_type' => ['houseType' => 'name_ld'],
    ];

    const ADMIN = 'admin@faromatics.com';
    protected $mailTransport;
    protected $serviceContainer;


    protected function __construct(ServiceManager $container) {
        $this->serviceContainer = $container;
        $this->config = $container->get('Config');
        $this->dbAdapter = $container->get(AdapterInterface::class);
        $this->mailTransport = $container->get(TransportInterface::class);
        $this->viewConfig['user']['canWrite'] = new \Laminas\Db\Sql\Expression('1');
        $this->viewConfig['user']['canRead'] = new \Laminas\Db\Sql\Expression('1');
    }


    protected function getTableGateway($table) {
        if (!isset($this->tableGateways[$table])) {
            $this->tableGateways[$table] = new \Laminas\Db\TableGateway\TableGateway($table, $this->dbAdapter);
        }
        return $this->tableGateways[$table];
    }


    protected function getMailTransport() {
        return $this->mailTransport;
    }

    protected function getNewGlobalId($type) {
        $serialNumber = null;
        $timeStamp = date("Y-m-d H:i:s");
        $table = $this->getTableGateway('global_id');

        while (!isset($serialNumber)) {
            $serialNumber = \Laminas\Math\Rand::getString(6, '123456789abcdefghijklmnopqrstuvwxyz', true);

            $conversion = bin2hex($serialNumber);
            $validator = substr('trwagmyfpdxbnjzsqvhlcke', hexdec($conversion) % 23, 1) ?? '0';
            $serialNumber = $serialNumber . $validator;
            $rowset = $table->select(['id' => $serialNumber]);
            if ($rowset->count() > 0) {
                // Serial number already in use
                $serialNumber = null;
            }
        }

        $data = [
            'id' => $serialNumber,
            'type' => $type,
            'created_by' => User::FAROMATICS_CREATOR_IDENTITY,
            'date_created' => $timeStamp,
        ];
        $table->insert($data);
        return $serialNumber;
    }


    protected function createdBy($table, $userId) {
        $data = [
            'created_by' => User::FAROMATICS_CREATOR_IDENTITY,
        ];
        $table = $this->getTableGateway($table);
        $table->update($data, ['id' => $userId]);
    }

    protected function modifiedBy($table, $userId) {
        $timeStamp = time();
        $data = [
            'modified_by' => User::FAROMATICS_CREATOR_IDENTITY,
            //'date_modified' => $timeStam
        ];
        $table = $this->getTableGateway($table);
        $table->update($data, ['id' => $userId]);
    }


    protected function getMyCreator($userId) {
        $select = new Select;
        $select->from(['u' => 'user'])
            ->where
            ->nest()
            ->equalTo('u.id', $userId)
            ->and
            ->notEqualTo('u.created_by', '0000000')
            ->unnest();
        $results = $this->getTableGateway('user');

        return $results->selectWith($select)->current()->created_by ?? null;
    }


    protected function insert($entity, $data) {
        $table = $this->getTableGateway($entity);
        $table->insert($data);
    }


    protected function update($entity, $data, $params) {
        $table = $this->getTableGateway($entity);
        $table->update($data, $params);
    }


    protected function isMyEntity($entity, $entityId, $userId) {
        $table = $this->getTableGateway($entity);
        $rowset = $table->select(['id' => $entityId, 'created_by' => $userId])->current();
        return isset($rowset) ? true : false;
    }

    protected function returnEntity($entity, $params) {
        $table = $this->getTableGateway($entity);
        $rowset = $table->select($params);
        return $rowset->current();
    }



    public function getUserRoleInEntity($param, $groupCol) {
        $email = $this->returnEntity('user', ['id' => $param['u.id']])->email;
        $select = new Select;
        $profileId = ['profileId' => (new \Laminas\Db\Sql\Expression('IFNULL(up.profile_id, if(STRCMP(f.created_by, "' . $param['u.id'] . '") = 0, 2, 6))'))];

        $rhhLit = new \Laminas\Db\Sql\Literal('rhh.robot_id = r.id and rhh.to IS NULL');
        $joins = [
            ['up', 'user_profile', 'u.id = up.user_id', 'inner'],
            ['rup', 'robot_user_profile', 'up.id = rup.user_profile_id', 'inner'],
            ['r', 'robot', 'rup.robot_id = r.id', 'inner'],
            ['rhh', 'robot_house_history', $rhhLit, 'left'],
            ['h', 'house', 'h.id = rhh.house_id or h.created_by = u.id', 'inner'],
            ['round', 'round', 'round.house_id = h.id', 'left'],
            ['f', 'farm', 'f.id = h.farm_id or f.created_by = u.id', 'inner'],
            ['an', 'alert_notification', 'an.robot_id = r.id and an.user_id = u.id', 'inner'],
            ['d', 'diary', 'd.round_id = round.id or d.created_by = u.id', 'inner'],
        ];

        $idx = 6;
        switch ($param) {
            case array_key_exists('an.id', $param):
                $idx = 7;
                break;
            case array_key_exists('d.id', $param):
                $idx = 8;
                break;
        }

        $select->from(['u' => 'user']);
        $select->join([$joins[0][0] => $joins[0][1]], $joins[0][2], [], $joins[0][3]);
        $select->columns($profileId);
        foreach (range(1, $idx) as $i) {
            $select->join([$joins[$i][0] => $joins[$i][1]], $joins[$i][2], [], $joins[$i][3]);
        }
        $select->group($groupCol)->where($param);

        $results = $this->getTableGateway('user');

        return $email == self::ADMIN ? '1' : $results->selectWith($select)->current()->profileId ?? '6';
    }



    protected function returnEntityView($entity, $param, $rights = null, $groupCol) {
        $select = new Select;
        $select->from(['u' => 'user'])
            ->columns($entity == 'user' ? $this->viewConfig['user'] : [])
            ->join(['up' => 'user_profile'], 'u.id = up.user_id', ['role' => 'profile_id'], 'left')
            ->columns($rights)
            ->join(['rup' => 'robot_user_profile'], 'up.id = rup.user_profile_id', [], 'left')
            ->join(['r' => 'robot'], 'rup.robot_id = r.id', $entity == 'robot' ? $this->viewConfig['robot'] : [], 'left')
            ->join(['rhh' => 'robot_house_history'], new \Laminas\Db\Sql\Literal('rhh.robot_id = r.id and rhh.to IS NULL'), [], 'left')
            ->join(['h' => 'house'], 'h.id = rhh.house_id or h.created_by = u.id', $entity == 'house' ? $this->viewConfig['house'] : [], 'left')
            ->join(['round' => 'round'], 'round.house_id = h.id', $entity == 'round' ? $this->viewConfig['round'] : [], 'left')
            ->join(['f' => 'farm'], 'f.id = h.farm_id or f.created_by = u.id', $entity == 'farm' ? $this->viewConfig['farm'] : [], 'left')
            ->join(['an' => 'alert_notification'], 'an.robot_id = r.id and an.user_id = u.id', $entity == 'alert' ? $this->viewConfig['alert'] : [], 'left')
            ->join(['d' => 'diary'], 'round.id = d.round_id or d.created_by = u.id', $entity == 'diary' ? $this->viewConfig['diary'] : [], 'left')
            ->join(['c' => 'climate'], 'h.climate_id = c.id', $entity == 'house' ? ['climateType' => 'name_ld'] : [], 'left')
            ->join(['cc' => 'climate_controller'], 'h.climate_controller_id = cc.id', $entity == 'house' ? ['climateController' => 'name'] : [], 'left')
            ->join(['ht' => 'house_type'], 'h.house_type_id = ht.id', $entity == 'house' ? ['houseType' => 'name_ld'] : [], 'left')
            ->group($groupCol)
            ->where($param);

        $results = $this->getTableGateway('user');
        return $results->selectWith($select)->current() ?? null;
    }


    protected function fetchEntities($userId, $entity, $param, $rights = null, $groupCol) {
        $creator = $this->getMyCreator($userId);
        $searchParams = [
            'range' => [
                'from' => ($entity === 'round' || $entity === 'alert') ? ($param['range'] != 'false' ? explode(" ", $param['range'])[0] : '1900-01-01') : null,
                'to' => ($entity == 'round' || $entity === 'alert') ? ($param['range'] != 'false' ? explode(" ", $param['range'])[1] : '2222-01-01') : null,
            ],
            'status' => isset($param['status']) ? ($param['status'] != 'true' ? $param['status'] : '1') : '1',
            'exportable' => isset($param['exportable']) ? $param['exportable'] : null,
            'ids' => [
                'farm' => isset($param['farmId']) ? ($param['farmId'] != 'false' ? $param['farmId'] : null) : null,
                'robot' => isset($param['robotId']) ? ($param['robotId'] != 'false' ? $param['robotId'] : null) : null,
                'house' => isset($param['houseId']) ? ($param['houseId'] != 'false' ? $param['houseId'] : null) : null
            ],
            'search' => isset($param['search']) ? ($param['search'] != 'false' ? $param['search'] : null) : null
        ];

$offset = isset($param['offset']) && is_numeric($param['offset']) ? (int) $param['offset'] : 0;
$limit = isset($param['limit']) && is_numeric($param['limit']) ? (int) $param['limit'] : 0;

        $queryBuilder = new QueryBuilder;
        $select = $queryBuilder->buildQuery($userId, $creator, $entity, $rights, $groupCol, $offset, $limit, $searchParams);
        $results = $this->getTableGateway('user');
        return $results->selectWith($select)->toArray();
    }


    protected function fetchAdmin($entity, $param) {
        $this->viewConfigAdmin[$entity]['canWrite'] = new \Laminas\Db\Sql\Expression('1');
        $this->viewConfigAdmin[$entity]['canRead'] = new \Laminas\Db\Sql\Expression('1');
        $this->viewConfigAdmin[$entity]['role'] = new \Laminas\Db\Sql\Expression('1');
        $view = $this->viewConfigAdmin[$entity];
        $offset = (int) $param['offset'];
        $limit = (int) $param['limit'];
        $queryBuilder = new QueryBuilder;
        $searchParams = [
            'range' => [
                'from' => $entity == 'round' ? ($param['range'] != 'false' ? explode(" ", $param['range'])[0] : '1900-01-01') : null,
                'to' => $entity == 'round' ? ($param['range'] != 'false' ? explode(" ", $param['range'])[1] : '2222-01-01') : null,
            ],
            'status' => isset($param['status']) ? ($param['status'] != 'true' ? $param['status'] : '1') : '1',
            'ids' => [
                'farm' => isset($param['farmId']) ? ($param['farmId'] != 'false' ? $param['farmId'] : null) : null,
                'robot' => isset($param['robotId']) ? ($param['robotId'] != 'false' ? $param['robotId'] : null) : null,
                'house' => isset($param['houseId']) ? ($param['houseId'] != 'false' ? $param['houseId'] : null) : null
            ],
            'search' => isset($param['search']) ? ($param['search'] != 'false' ? $param['search'] : null) : null
        ];
        $select = $queryBuilder->buildAdminQuery($entity, $view, $searchParams, $offset, $limit);
        $results = $this->getTableGateway($entity);
        $result = $results->selectWith($select);
        return $result->toArray();
    }


    function getTargetsForProductionCycleDay($roundId, $day) {
        $target = $this->returnEntity('targets', ['round_id' => $roundId])->targets;
        $command = "python3 /apps/chickenboy-site/scripts/interpolation/interpolate.py " . $roundId;
        exec($command, $output, $exitCode);
        $arr = [];
        if (is_null($target)) {
            $targetId = $this->getNewGlobalId('targets');
            $targetsData = [
                'targets' => $output[0],
                'round_id' => $roundId,
                'id' => $targetId,
                'created_by' => '0000000',
            ];
            $this->insert('targets', $targetsData);
            $target = $this->returnEntity('targets', ['round_id' => $roundId])->targets;
            $targets = json_decode($target, true, 512, JSON_BIGINT_AS_STRING);
            foreach ($targets[$day] as $key => $target) {
                if (isset($this->config['observable_id'][$key])) {
                    $arr[$this->config['observable_id'][$key]] = $target;
                }
            }
            return $arr;

        } else {
            $targets = json_decode($target, true, 512, JSON_BIGINT_AS_STRING);

            foreach ($targets[$day] as $key => $target) {
                if (isset($this->config['observable_id'][$key])) {
                    $arr[$this->config['observable_id'][$key]] = $target;
                }
            }
            return $arr;
        }
    }
}