Source of file NextDomAjax.php

Size: 16,677 Bytes - Last Modified: 2020-10-24T02:46:31+00:00

/home/travis/build/NextDom/nextdom-core/src/Ajax/NextDomAjax.php

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
<?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/>.
 */

namespace NextDom\Ajax;

use NextDom\Enums\AjaxParams;
use NextDom\Enums\NextDomObj;
use NextDom\Enums\UserRight;
use NextDom\Exceptions\CoreException;
use NextDom\Helpers\AjaxHelper;
use NextDom\Helpers\AuthentificationHelper;
use NextDom\Helpers\DBHelper;
use NextDom\Helpers\FileSystemHelper;
use NextDom\Helpers\NextDomHelper;
use NextDom\Helpers\SystemHelper;
use NextDom\Helpers\TimeLineHelper;
use NextDom\Helpers\Utils;
use NextDom\Managers\BackupManager;
use NextDom\Managers\CacheManager;
use NextDom\Managers\CmdManager;
use NextDom\Managers\ConfigManager;
use NextDom\Managers\JeeObjectManager;
use NextDom\Managers\PluginManager;
use NextDom\Managers\ScenarioManager;
use NextDom\Managers\UserManager;
use NextDom\Managers\ViewManager;
use NextDom\Managers\ImageManager;
use NextDom\Model\Entity\Listener;

/**
 * Class NextDomAjax
 * @package NextDom\Ajax
 */
class NextDomAjax extends BaseAjax
{
    protected $NEEDED_RIGHTS = UserRight::NOTHING;
    protected $MUST_BE_CONNECTED = true;
    protected $CHECK_AJAX_TOKEN = false;

    /**
     * Get documentation link
     *
     * @throws CoreException
     */
    public function getDocumentationUrl()
    {
        $documentationUrl = '';
        AuthentificationHelper::isConnectedOrFail();
        $this->ajax->checkToken();

        $pluginId = Utils::init(AjaxParams::PLUGIN);
        if ($pluginId !== '') {
            $plugin = PluginManager::byId($pluginId);
            if (is_object($plugin) && $plugin->getDocumentation() !== '') {
                $documentationUrl = $plugin->getDocumentation();
            }
        } else {
            $adminPages = ['api', 'cache', 'network', 'security', 'services', 'realtime', 'commandes', 'eqlogic', 'general', 'links'];
            $noDocPages = ['connection', 'firstUse', 'note'];
            $redirectPage = ['view_edit' => 'view',
                'plan' => 'design',
                'scenarioAssist' => 'scenario',
                'users' => 'user',
                'timeline' => 'history',
                'interact_config' => 'interact',
                'log_config' => 'log',
                'summary' => 'display',
                'report_config' => 'report',
                'update-view' => 'update'];

            $documentationPage = Utils::init('page');
            if (in_array($documentationPage, $noDocPages)) {
                $documentationUrl = 'https://jeedom.github.io/documentation/';
            } else {
                if (in_array($documentationPage, $adminPages)) {
                    $documentationPage = 'administration';
                } elseif (array_key_exists($documentationPage, $redirectPage)) {
                    $documentationPage = $redirectPage[$documentationPage];
                }
                $documentationUrl = 'https://jeedom.github.io/core/' . ConfigManager::byKey('language', 'core', 'fr_FR') . '/' . secureXSS($documentationPage);
            }
        }
        if ($documentationUrl !== '') {
            $this->ajax->success($documentationUrl);
        } else {
            $this->ajax->error(__('Aucune documentation'));
        }
    }

    public function addWarnme()
    {
        AuthentificationHelper::isConnectedOrFail();
        $this->ajax->checkToken();
        $cmd = CmdManager::byId(Utils::init(AjaxParams::CMD_ID));
        if (!is_object($cmd)) {
            throw new CoreException(__('Commande non trouvée : ') . Utils::init(AjaxParams::CMD_ID));
        }
        $listener = new Listener();
        $listener->setClass('interactQuery');
        $listener->setFunction('warnMeExecute');
        $listener->addEvent($cmd->getId());
        $options = [
            'type' => 'cmd',
            'cmd_id' => $cmd->getId(),
            'name' => $cmd->getHumanName(),
            'test' => Utils::init('test'),
            'reply_cmd' => Utils::init('reply_cmd', UserManager::getStoredUser()->getOptions('notification::cmd')),
        ];
        $listener->setOption($options);
        $listener->save(true);
        $this->ajax->success();
    }


    public function ssh()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $command = Utils::init(AjaxParams::COMMAND);
        if (strpos($command, '2>&1') === false && strpos($command, '>') === false) {
            $command .= ' 2>&1';
        }
        $output = [];
        exec($command, $output);
        $this->ajax->success(implode("\n", $output));
    }

    public function db()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        if (Utils::init('command', '') !== '') {
            $this->ajax->success(DBHelper::getAll(Utils::init(AjaxParams::COMMAND)));
        } else {
            $this->ajax->error(__('Aucune requête à exécuter'));
        }
    }

    public function dbcorrectTable()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        DBHelper::compareAndFix(json_decode(file_get_contents(NEXTDOM_ROOT . '/install/database.json'), true), Utils::init('table'));
        $this->ajax->success();

    }

    public function health()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $this->ajax->success(NextDomHelper::health());
    }

    public function update()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        NextDomHelper::update();
        $this->ajax->success();
    }

    public function clearDate()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $cache = CacheManager::byKey('NextDomHelper::lastDate');
        $cache->remove();
        $this->ajax->success();
    }

    public function backup()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        BackupManager::backup(true);
        $this->ajax->success();
    }

    public function restoreLocal()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        BackupManager::restore(BackupManager::getBackupDirectory() . "/" . Utils::init(AjaxParams::BACKUP), true);
        $this->ajax->success();
    }

    public function removeBackup()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        BackupManager::removeBackup(BackupManager::getBackupDirectory() . "/" . Utils::init(AjaxParams::BACKUP));
        $this->ajax->success();
    }

    public function listBackup()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $this->ajax->success(BackupManager::listBackup());
    }

    public function getConfiguration()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $this->ajax->success(NextDomHelper::getConfiguration(Utils::init(AjaxParams::KEY), Utils::init(AjaxParams::DEFAULT)));
    }

    public function resetHwKey()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        ConfigManager::save('NextDomHelper::installKey', '');
        $this->ajax->success();
    }

    public function resetHour()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        CacheManager::delete('hour');
        $this->ajax->success();
    }

    public function backupupload()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $uploadDir = BackupManager::getBackupDirectory();
        Utils::readUploadedFile($_FILES, "file", $uploadDir, 1000, [".gz"]);
        $this->ajax->success();
    }

    public function haltSystem()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        NextDomHelper::haltSystem();
        $this->ajax->success();
    }

    public function rebootSystem()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        NextDomHelper::rebootSystem();
        $this->ajax->success();
    }

    public function forceSyncHour()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        NextDomHelper::forceSyncHour();
        $this->ajax->success();
    }

    public function getGraphData()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $resultObject = null;
        $type = Utils::init('filter_type');
        if ($type !== '') {
            $resultObject = $type::byId(Utils::init('filter_id'));
            if (!is_object($resultObject)) {
                throw new CoreException(__('Type :') . Utils::init('filter_type') . __(' avec id : ') . Utils::init('filter_id') . __(' inconnu'));
            }
            $this->ajax->success($resultObject->getLinkData());
        } else {
            $this->ajax->error(__('Aucun filtre'));
        }
    }

    public function getTimelineEvents()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $return = [];
        $events = TimeLineHelper::getTimelineEvent();
        foreach ($events as $event) {
            $info = null;
            if ($event['type'] === NextDomObj::CMD) {
                $info = CmdManager::timelineDisplay($event);
            } elseif ($event['type'] === NextDomObj::SCENARIO) {
                $info = ScenarioManager::timelineDisplay($event);
            }
            if ($info != null) {
                $return[] = $info;
            }
        }
        $this->ajax->success($return);
    }

    public function consistency()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        SystemHelper::consistency();
        $this->ajax->success();
    }

    public function cleanFileSystemRight()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        SystemHelper::cleanFileSystemRight();
        $this->ajax->success();
    }

    public function removeTimelineEvents()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        TimeLineHelper::removeTimelineEvent();
        $this->ajax->success();
    }

    public function getFileFolder()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $this->ajax->success(FileSystemHelper::ls(Utils::init('path'), '*', false, [Utils::init('type')]));
    }

    public function getFileContent()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $filePath = Utils::init('path');
        $pathinfo = pathinfo($filePath);
        $extension = Utils::array_key_default($pathinfo, "extension", "<no-ext>");
        if (!in_array($extension, ['php', 'js', 'json', 'sql', 'ini', 'html', 'py', 'css'])) {
            throw new CoreException(__('Vous ne pouvez éditer ce type d\'extension : ' . $extension));
        }
        if (!is_writable($filePath)) {
            throw new CoreException(__('Vous n\'avez pas les droits pour éditer ce fichier.'));
        }
        $this->ajax->success(file_get_contents(Utils::init('path')));
    }

    public function setFileContent()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $filePath = Utils::init('path');
        $pathInfo = pathinfo($filePath);
        $extension = Utils::array_key_default($pathInfo, "extension", "<no-ext>");
        if (!in_array($extension, ['php', 'js', 'json', 'sql', 'ini', 'html', 'py', 'css'])) {
            throw new CoreException(__('Vous ne pouvez éditer ce type d\'extension : ') . $extension);
        }
        if (!is_writable($filePath)) {
            throw new CoreException(__('Vous n\'avez pas les droits pour éditer ce fichier.'));
        }
        $this->ajax->success(file_put_contents($filePath, Utils::init('content')));
    }

    public function deleteFile()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $pathinfo = pathinfo(Utils::init('path'));
        $extension = Utils::array_key_default($pathinfo, "extension", "<no-ext>");
        if (!in_array($extension, ['php', 'js', 'json', 'sql', 'ini', 'css'])) {
            throw new CoreException(__('Vous ne pouvez éditer ce type d\'extension : ' . $extension));
        }
        $this->ajax->success(unlink(Utils::init('path')));
    }

    public function createFile()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $pathinfo = pathinfo(Utils::init('name'));
        $extension = Utils::array_key_default($pathinfo, "extension", "<no-ext>");
        if (!in_array($extension, ['php', 'js', 'json', 'sql', 'ini', 'css'])) {
            throw new CoreException(__('Vous ne pouvez éditer ce type d\'extension : ' . $extension));
        }
        touch(Utils::init('path') . Utils::init('name'));
        if (!file_exists(Utils::init('path') . Utils::init('name'))) {
            throw new CoreException(__('Impossible de créer le fichier, vérifiez les droits'));
        }
        $this->ajax->success();
    }

    public function emptyRemoveHistory()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        unlink(NEXTDOM_DATA . '/data/remove_history.json');
        $this->ajax->success();
    }

    public function version()
    {
        $version['nextdom'] = NextDomHelper::getNextdomVersion();
        $version['jeedom'] = NextDomHelper::getJeedomVersion();
        $this->ajax->success($version);
    }

    public function uploadImageIcon()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $imageDir = ImageManager::getDirectory();
        Utils::readUploadedFile($_FILES, "file", $imageDir, 1000, ['.jpg', '.png','.gif']);
        $this->ajax->success('data/img/' . $_FILES['file']['name']);
    }

    public function removeImageIcon() {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $filepath = ImageManager::getDirectory() . Utils::initFilename('filename');
        if(!file_exists($filepath)){
            throw new CoreException(__('Fichier introuvable, impossible de le supprimer'));
        }
        unlink($filepath);
        if(file_exists($filepath)){
            throw new CoreException(__('Impossible de supprimer le fichier'));
        }
        $this->ajax->success();
    }

    public function cleanDatabase()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        NextDomHelper::cleanDatabase();
        $this->ajax->success();
    }

    public function massEditSave()
    {
        AuthentificationHelper::isConnectedAsAdminOrFail();
        $this->ajax->checkToken();
        $type = Utils::init('type');
        if ($type === 'widgets') {
            $type = 'widget';
        }
        $type = ucfirst($type);
        if (!class_exists($type)) {
            throw new CoreException(__('Type non trouvé : ') . $type);
        }
        $datas = is_json(Utils::init('objects'), []);
        if (count($datas) > 0) {
            foreach ($datas as $data) {
                $manager = $type . 'Manager';
                $object = $manager::byId($data['id']);
                if (!is_object($object)) {
                    continue;
                }
                Utils::a2o($objectToSave, $data);
                try {
                    $objectToSave->save(true);
                } catch (\Exception $e) {
                    var_dump($e);
                }
            }
        }
        $this->ajax->success();
    }
}