Source of file JeeObjectManager.php

Size: 20,713 Bytes - Last Modified: 2020-10-24T02:46:31+00:00

/home/travis/build/NextDom/nextdom-core/src/Managers/JeeObjectManager.php

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
<?php
/* This file is part of Jeedom.
 *
 * Jeedom is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Jeedom is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Jeedom. If not, see <http://www.gnu.org/licenses/>.
 */

/* This file is part of NextDom.
 *
 * NextDom is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * NextDom is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with NextDom. If not, see <http://www.gnu.org/licenses/>.
 */

namespace NextDom\Managers;

use NextDom\Enums\CmdSubType;
use NextDom\Enums\CmdType;
use NextDom\Enums\Common;
use NextDom\Enums\ConfigKey;
use NextDom\Enums\NextDomObj;
use NextDom\Enums\NextDomFolder;
use NextDom\Exceptions\CoreException;
use NextDom\Helpers\DBHelper;
use NextDom\Helpers\NextDomHelper;
use NextDom\Helpers\Utils;
use NextDom\Helpers\FileSystemHelper;
use NextDom\Managers\Parents\BaseManager;
use NextDom\Managers\Parents\CommonManager;
use NextDom\Model\Entity\JeeObject;
use NextDom\Model\Entity\Update;
use NextDom\Model\Entity\User;

/**
 * Class ObjectManager
 * @package NextDom\Managers
 */
class JeeObjectManager extends BaseManager
{
    use CommonManager;
    const DB_CLASS_NAME = '`object`';
    const CLASS_NAME = JeeObject::class;

    /**
     * Get an object by with his name.
     *
     * @param string $name
     * @return JeeObject|null
     * @throws \Exception
     */
    public static function byName($name)
    {
        return static::getOneByClauses(['name' => $name]);
    }

    /**
     * Build tree of all objects
     *
     * @param mixed $nodeObject Current root object
     * @param bool $visible Filter only visible objects
     *
     * @return JeeObject[]
     *
     * @throws \Exception
     */
    public static function buildTree($nodeObject = null, $visible = true)
    {
        $result = [];
        if (!is_object($nodeObject)) {
            $objectsList = self::getRootObjects(true, $visible);
        } else {
            $objectsList = $nodeObject->getChild($visible);
        }
        if (is_array($objectsList) && count($objectsList) > 0) {
            foreach ($objectsList as $jeeObject) {
                $result[] = $jeeObject;
                $result = array_merge($result, self::buildTree($jeeObject, $visible));
            }
        }
        return $result;
    }

    /**
     * Get root objects.
     *
     * @param bool $all False return only the first, True return all roots objects
     * @param bool $onlyVisible Filter only visible objects
     *
     * @return array|mixed|null
     *
     * @throws \Exception
     */
    public static function getRootObjects($all = false, $onlyVisible = false)
    {
        $fetchType = DBHelper::FETCH_TYPE_ALL;
        $sql = static::getBaseSQL() . '
                WHERE father_id IS NULL';
        if ($onlyVisible) {
            $sql .= ' AND `isVisible` = 1';
        }
        $sql .= ' ORDER BY `position`';
        if ($all === false) {
            $sql .= ' LIMIT 1';
            $fetchType = DBHelper::FETCH_TYPE_ROW;
        }
        return DBHelper::Prepare($sql, [], $fetchType, \PDO::FETCH_CLASS, self::CLASS_NAME);
    }

    /**
     * @param User $user
     * @return array|mixed|null
     * @throws CoreException
     */
    public static function getDefaultUserRoom(User $user)
    {
        $rootRoomId = $user->getOptions('defaultDashboardObject');
        if (empty($rootRoomId)) {
            $defaultRoom = self::getRootObjects();
        } else {
            $defaultRoom = self::byId($rootRoomId);
        }
        return $defaultRoom;
    }

    /**
     * @TODO: ???
     *
     * Data restrictions :
     *  - $restrict['object'][OBJECT_ID] : Skip objects
     *  -
     *
     * @param array $restrict Data restrictions
     *
     * @return array
     *
     * @throws \Exception
     */
    public static function fullData($restrict = [])
    {
        $result = [];
        foreach (self::all(true) as $jeeObject) {
            if (!isset($restrict[NextDomObj::OBJECT]) || !is_array($restrict[NextDomObj::OBJECT]) || isset($restrict[NextDomObj::OBJECT][$jeeObject->getId()])) {
                $object_return = Utils::o2a($jeeObject);
                $object_return['eqLogics'] = [];
                $objectGetEqLogic = $jeeObject->getEqLogic(true, true);
                foreach ($objectGetEqLogic as $eqLogic) {
                    if (!isset($restrict[NextDomObj::EQLOGIC]) || !is_array($restrict[NextDomObj::EQLOGIC]) || isset($restrict[NextDomObj::EQLOGIC][$eqLogic->getId()])) {
                        $eqLogic_return = Utils::o2a($eqLogic);
                        $eqLogic_return['cmds'] = [];
                        $eqLogicGetCmd = $eqLogic->getCmd();
                        foreach ($eqLogicGetCmd as $cmd) {
                            if (!isset($restrict[NextDomObj::CMD]) || !is_array($restrict[NextDomObj::CMD]) || isset($restrict[NextDomObj::CMD][$cmd->getId()])) {
                                $cmd_return = Utils::o2a($cmd);
                                if ($cmd->isType(CmdType::INFO)) {
                                    $cmd_return['state'] = $cmd->execCmd();
                                }
                                $eqLogic_return['cmds'][] = $cmd_return;
                            }
                        }
                        $object_return['eqLogics'][] = $eqLogic_return;
                    }
                }
                $result[] = $object_return;
            }
        }
        return $result;
    }

    /**
     * Get all objects.
     *
     * @param bool $onlyVisible Filter only visible objects
     *
     * @return JeeObject[]|null
     *
     * @throws \Exception
     */
    public static function all($onlyVisible = false)
    {
        $clauses = [];
        if ($onlyVisible) {
            $clauses['isVisible'] = 1;
        }
        return static::getMultipleByClauses($clauses, ['position', 'name', 'father_id']);
    }

    /**
     * @param $father_id
     * @param $onlyVisible
     * @return mixed|null
     * @throws CoreException
     * @throws \ReflectionException
     */
    public static function getChildren($father_id, $onlyVisible)
    {
        $clauses = ['father_id' => $father_id];
        if ($onlyVisible) {
            $clauses['isVisible'] = 1;
        }
        return static::getMultipleByClauses($clauses, 'position');
    }

    /**
     * @TODO: ???
     *
     * @return array
     * @throws \Exception
     */
    public static function deadCmd()
    {
        $result = [];
        foreach (self::all() as $jeeObject) {
            foreach ($jeeObject->getConfiguration(Common::SUMMARY, []) as $key => $summary) {
                foreach ($summary as $cmdInfo) {
                    if (!CmdManager::byId(str_replace('#', '', $cmdInfo['cmd']))) {
                        $result[] = ['detail' => 'Résumé ' . $jeeObject->getName(), 'help' => ConfigManager::byKey(ConfigKey::OBJECT_SUMMARY)[$key]['name'], 'who' => $cmdInfo['cmd']];
                    }
                }
            }
        }
        return $result;
    }

    /**
     * @TODO ???
     *
     * @param string $cmdId
     * @throws \Exception
     */
    public static function checkSummaryUpdate(string $cmdId)
    {
        $jeeObjects = self::searchConfiguration('#' . $cmdId . '#');
        if (count($jeeObjects) == 0) {
            return;
        }
        $toRefreshCmd = [];
        $global = [];
        foreach ($jeeObjects as $jeeObject) {
            $summaries = $jeeObject->getConfiguration(Common::SUMMARY);
            if (!is_array($summaries)) {
                continue;
            }
            $event = [Common::OBJECT_ID => $jeeObject->getId(), Common::KEYS => []];
            foreach ($summaries as $key => $summary) {
                foreach ($summary as $cmd_info) {
                    preg_match_all("/#([0-9]*)#/", $cmd_info['cmd'], $matches);
                    foreach ($matches[1] as $cmd_id) {
                        if ($cmd_id == $cmdId) {
                            $value = $jeeObject->getSummary($key);
                            $event['keys'][$key] = ['value' => $value];
                            $toRefreshCmd[] = ['key' => $key, 'object' => $jeeObject, 'value' => $value];
                            if ($jeeObject->getConfiguration('summary::global::' . $key, 0) == 1) {
                                $global[$key] = 1;
                            }
                        }
                    }
                }
            }
            $events[] = $event;
        }
        if (count($toRefreshCmd) > 0) {
            foreach ($toRefreshCmd as $value) {
                try {
                    $value['object']->setCache('summaryHtmldesktop', '');
                    $value['object']->setCache('summaryHtmlmobile', '');
                    if ($value['object']->getConfiguration('summary_virtual_id') == '') {
                        continue;
                    }
                    $virtual = EqLogicManager::byId($value['object']->getConfiguration('summary_virtual_id'));
                    if (!is_object($virtual)) {
                        $jeeObject->getConfiguration('summary_virtual_id', '');
                        $jeeObject->save();
                        continue;
                    }
                    $cmd = $virtual->getCmd(CmdType::INFO, $value['key']);
                    if (!is_object($cmd)) {
                        continue;
                    }
                    $cmd->event($value['value']);
                } catch (\Exception $e) {
                }
            }
        }
        $events = [];
        if (count($global) > 0) {
            CacheManager::set('globalSummaryHtmldesktop', '');
            CacheManager::set('globalSummaryHtmlmobile', '');
            $event = [Common::OBJECT_ID => 'global', Common::KEYS => []];
            foreach ($global as $key => $value) {
                try {
                    $result = JeeObjectManager::getGlobalSummary($key);
                    if ($result === null) {
                        continue;
                    }
                    $event['keys'][$key] = ['value' => $result];
                    $virtual = EqLogicManager::byLogicalId('summaryglobal', 'virtual');
                    if (!is_object($virtual)) {
                        continue;
                    }
                    $cmd = $virtual->getCmd(CmdType::INFO, $key);
                    if (!is_object($cmd)) {
                        continue;
                    }
                    $cmd->event($result);
                } catch (\Exception $e) {
                }
            }
            $events[] = $event;
        }
        if (count($events) > 0) {
            EventManager::adds('jeeObject::summary::update', $events);
        }
    }

    /**
     * Search object configuration @TODO: ??
     *
     * @param string $search
     * @return array|mixed|null
     * @throws \Exception
     */
    public static function searchConfiguration(string $search)
    {
        $values = [
            'configuration' => '%' . $search . '%',
        ];
        $sql = static::getBaseSQL() . '
                WHERE `configuration` LIKE :configuration';
        return DBHelper::getAllObjects($sql, $values, self::CLASS_NAME);
    }

    /**
     * @TODO: ???
     *
     * @param string $key
     * @return float|null|string
     * @throws \Exception
     */
    public static function getGlobalSummary(string $key)
    {
        if ($key == '') {
            return null;
        }
        $def = ConfigManager::byKey(ConfigKey::OBJECT_SUMMARY);
        $jeeObjects = self::all();
        $value = [];
        foreach ($jeeObjects as $jeeObject) {
            if ($jeeObject->getConfiguration('summary::global::' . $key, 0) == 0) {
                continue;
            }
            $result = $jeeObject->getSummary($key, true);
            if ($result === null || !is_array($result)) {
                continue;
            }
            $value = array_merge($value, $result);
        }
        if (count($value) == 0) {
            return null;
        }
        if ($def[$key]['calcul'] == 'text') {
            return trim(implode(',', $value), ',');
        }
        return round(NextDomHelper::calculStat($def[$key]['calcul'], $value), 1);
    }

    /**
     * @TODO ???
     *
     * @param string $version
     *
     * @return string
     *
     * @throws \Exception
     */
    public static function getGlobalHtmlSummary($version = 'desktop')
    {
        $cache = CacheManager::byKey('globalSummaryHtml' . $version);
        if ($cache->getValue() != '') {
            return $cache->getValue();
        }
        $jeeObjects = self::all();
        $def = ConfigManager::byKey(ConfigKey::OBJECT_SUMMARY);
        $values = [];
        $return = '<span class="objectSummaryglobal" data-version="' . $version . '">';
        foreach ($def as $key => $value) {
            foreach ($jeeObjects as $jeeObject) {
                if ($jeeObject->getConfiguration('summary::global::' . $key, 0) == 0) {
                    continue;
                }
                if (!isset($values[$key])) {
                    $values[$key] = [];
                }
                $result = $jeeObject->getSummary($key, true);
                if ($result === null || !is_array($result)) {
                    continue;
                }
                $values[$key] = array_merge($values[$key], $result);
            }
        }
        $margin = ($version == 'desktop') ? 4 : 2;

        foreach ($values as $key => $value) {
            if (count($value) == 0) {
                continue;
            }
            $style = '';
            $allowDisplayZero = $def[$key]['allowDisplayZero'];
            if ($def[$key]['calcul'] == 'text') {
                $result = trim(implode(',', $value), ',');
                $allowDisplayZero = 1;
            } else {
                $result = round(NextDomHelper::calculStat($def[$key]['calcul'], $value), 1);

            }
            if ($allowDisplayZero == 0 && $result == 0) {
                $style = 'display:none;';
            }
            $return .= '<span class="objectSummaryParent cursor" data-summary="' . $key . '" data-object_id="" style="margin-right:' . $margin . 'px;' . $style . '" data-displayZeroValue="' . $allowDisplayZero . '">';
            $return .= $def[$key]['icon'] . ' <sup><span class="objectSummary' . $key . '">' . $result . '</span> ' . $def[$key]['unit'] . '</sup>';
            $return .= '</span>';
        }
        $return = trim($return) . '</span>';
        CacheManager::set('globalSummaryHtml' . $version, $return);
        return $return;
    }

    /**
     * @TODO ???
     *
     * @param string $key
     * @throws \Throwable
     */
    public static function createSummaryToVirtual($key = '')
    {
        if ($key == '') {
            return;
        }
        $def = ConfigManager::byKey(ConfigKey::OBJECT_SUMMARY);
        if (!isset($def[$key])) {
            return;
        }
        try {
            $plugin = PluginManager::byId('virtual');
            if (!is_object($plugin)) {
                $update = UpdateManager::byLogicalId('virtual');
                if (!is_object($update)) {
                    $update = new Update();
                }
                $update->setLogicalId('virtual');
                $update->setSource('market');
                $update->setConfiguration('version', 'stable');
                $update->save();
                $update->doUpdate();
                sleep(2);
                $plugin = PluginManager::byId('virtual');
            }
        } catch (\Exception $e) {
            $update = UpdateManager::byLogicalId('virtual');
            if (!is_object($update)) {
                $update = new Update();
            }
            $update->setLogicalId('virtual');
            $update->setSource('market');
            $update->setConfiguration('version', 'stable');
            $update->save();
            $update->doUpdate();
            sleep(2);
            $plugin = PluginManager::byId('virtual');
        }
        if (!$plugin->isActive()) {
            $plugin->setIsEnable(1);
        }
        if (!is_object($plugin)) {
            throw new CoreException(__('Le plugin virtuel doit être installé'));
        }
        if (!$plugin->isActive()) {
            throw new CoreException(__('Le plugin virtuel doit être actif'));
        }

        $virtual = EqLogicManager::byLogicalId('summaryglobal', 'virtual');
        if (!is_object($virtual)) {
            /** @noinspection PhpUndefinedClassInspection */
            $virtual = new \virtual();
            $virtual->setName(__('Résumé Global'));
            $virtual->setIsVisible(0);
            $virtual->setIsEnable(1);
        }
        $virtual->setIsEnable(1);
        $virtual->setLogicalId('summaryglobal');
        $virtual->setEqType_name('virtual');
        $virtual->save();
        $cmd = $virtual->getCmd(CmdType::INFO, $key);
        if (!is_object($cmd)) {
            /** @noinspection PhpUndefinedClassInspection */
            $cmd = new \virtualCmd();
            $cmd->setName($def[$key]['name']);
            $cmd->setIsHistorized(1);
        }
        $cmd->setEqLogic_id($virtual->getId());
        $cmd->setLogicalId($key);
        $cmd->setType(CmdType::INFO);
        if ($def[$key]['calcul'] == 'text') {
            $cmd->setSubtype(CmdSubType::STRING);
        } else {
            $cmd->setSubtype(CmdSubType::NUMERIC);
        }
        $cmd->setUnite($def[$key]['unit']);
        $cmd->save();

        foreach (self::all() as $jeeObject) {
            $summaries = $jeeObject->getConfiguration(Common::SUMMARY);
            if (!is_array($summaries)) {
                continue;
            }
            if (!isset($summaries[$key]) || !is_array($summaries[$key]) || count($summaries[$key]) == 0) {
                continue;
            }
            $virtual = EqLogicManager::byLogicalId(Common::SUMMARY . $jeeObject->getId(), 'virtual');
            if (!is_object($virtual)) {
                /** @noinspection PhpUndefinedClassInspection */
                $virtual = new \virtual();
                $virtual->setName(__('Résumé'));
                $virtual->setIsVisible(0);
                $virtual->setIsEnable(1);
            }
            $virtual->setIsEnable(1);
            $virtual->setLogicalId(Common::SUMMARY . $jeeObject->getId());
            $virtual->setEqType_name('virtual');
            $virtual->setObject_id($jeeObject->getId());
            $virtual->save();
            $jeeObject->setConfiguration('summary_virtual_id', $virtual->getId());
            $jeeObject->save();
            $cmd = $virtual->getCmd(CmdType::INFO, $key);
            if (!is_object($cmd)) {
                /** @noinspection PhpUndefinedClassInspection */
                $cmd = new \virtualCmd();
                $cmd->setName($def[$key]['name']);
                $cmd->setIsHistorized(1);
            }
            $cmd->setEqLogic_id($virtual->getId());
            $cmd->setLogicalId($key);
            $cmd->setType(CmdType::INFO);
            if ($def[$key]['calcul'] == 'text') {
                $cmd->setSubtype(CmdSubType::STRING);
            } else {
                $cmd->setSubtype(CmdSubType::NUMERIC);
            }
            $cmd->setUnite($def[$key]['unit']);
            $cmd->save();
        }
    }

    /**
     * Clean plan images
     *
     * @param int $planHeaderId
     */
    public static function cleanPlanImageFolder(int $planHeaderId) {
        $filesToClean = FileSystemHelper::ls(NextDomFolder::PLAN_IMAGE, NextDomObj::PLAN_HEADER . $planHeaderId . '*');
        foreach ($filesToClean as $fileToClean) {
            unlink(NextDomFolder::PLAN_IMAGE . $fileToClean);
        }
    }
}