Source of file ScenarioElement.php
Size: 18,916 Bytes - Last Modified: 2020-10-24T02:46:31+00:00
/home/travis/build/NextDom/nextdom-core/src/Model/Entity/ScenarioElement.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 | <?php /* This file is part of NextDom Software. * * 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 Software 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 Software. If not, see <http://www.gnu.org/licenses/>. */ namespace NextDom\Model\Entity; use NextDom\Enums\DateFormat; use NextDom\Enums\NextDomObj; use NextDom\Enums\ScenarioElementType; use NextDom\Enums\ScenarioExpressionType; use NextDom\Enums\ScenarioSubElementType; use NextDom\Exceptions\CoreException; use NextDom\Helpers\LogHelper; use NextDom\Helpers\NextDomHelper; use NextDom\Helpers\SystemHelper; use NextDom\Helpers\Utils; use NextDom\Managers\CronManager; use NextDom\Managers\ScenarioElementManager; use NextDom\Managers\ScenarioExpressionManager; use NextDom\Managers\ScenarioManager; use NextDom\Managers\ScenarioSubElementManager; use NextDom\Model\Entity\Parents\BaseEntity; use NextDom\Model\Entity\Parents\NameEntity; use NextDom\Model\Entity\Parents\OptionsEntity; use NextDom\Model\Entity\Parents\OrderEntity; use NextDom\Model\Entity\Parents\TypeEntity; /** * Scenarioelement * * ORM\Table(name="scenarioElement") * ORM\Entity */ class ScenarioElement extends BaseEntity { const TABLE_NAME = NextDomObj::SCENARIO_ELEMENT; use NameEntity, OptionsEntity, OrderEntity, TypeEntity; protected $_subelement; public function __construct() { if ($this->order === null) { $this->order = 0; } } public function remove() { foreach ($this->getSubElement() as $subElement) { $subElement->remove(); } return parent::remove(); } /** * @param string $_type * @return ScenarioSubElement[]|ScenarioSubElement * @throws \Exception */ public function getSubElement($_type = '') { if ($_type != '') { if (isset($this->_subelement[$_type]) && is_object($this->_subelement[$_type])) { return $this->_subelement[$_type]; } $this->_subelement[$_type] = ScenarioSubElementManager::byScenarioElementId($this->getId(), $_type); return $this->_subelement[$_type]; } else { if (isset($this->_subelement[-1]) && is_array($this->_subelement[-1]) && count($this->_subelement[-1]) > 0) { return $this->_subelement[-1]; } $this->_subelement[-1] = ScenarioSubElementManager::byScenarioElementId($this->getId(), $_type); return $this->_subelement[-1]; } } public function executeIf(&$_scenario) { if ($this->getSubElement(ScenarioSubElementType::IF)->getOptions('enable', 1) == 0) { return true; } $result = $this->getSubElement(ScenarioSubElementType::IF)->execute($_scenario); if (is_string($result) && strlen($result) > 1) { $_scenario->setLog(__('Expression non valide : ') . $result); return null; } if ($result) { if ($this->getSubElement(ScenarioSubElementType::IF)->getOptions('allowRepeatCondition', 0) == 1) { if ($this->getSubElement(ScenarioSubElementType::IF)->getOptions('previousState', -1) != 1) { $this->getSubElement(ScenarioSubElementType::IF)->setOptions('previousState', 1); $this->getSubElement(ScenarioSubElementType::IF)->save(); } else { $_scenario->setLog(__('Non exécution des actions pour cause de répétition')); return null; } } return $this->getSubElement(ScenarioSubElementType::THEN)->execute($_scenario); } if (!is_object($this->getSubElement(ScenarioSubElementType::ELSE))) { return null; } if ($this->getSubElement(ScenarioSubElementType::IF)->getOptions('allowRepeatCondition', 0) == 1) { if ($this->getSubElement(ScenarioSubElementType::IF)->getOptions('previousState', -1) != 0) { $this->getSubElement(ScenarioSubElementType::IF)->setOptions('previousState', 0); $this->getSubElement(ScenarioSubElementType::IF)->save(); } else { $_scenario->setLog(__('Non exécution des actions pour cause de répétition')); return null; } } return $this->getSubElement(ScenarioSubElementType::ELSE)->execute($_scenario); } public function executeAction(&$_scenario) { if ($this->getSubElement(ScenarioSubElementType::ACTION)->getOptions('enable', 1) == 0) { return true; } return $this->getSubElement(ScenarioSubElementType::ACTION)->execute($_scenario); } public function executeCode(&$_scenario) { if ($this->getSubElement(ScenarioSubElementType::CODE)->getOptions('enable', 1) == 0) { return true; } return $this->getSubElement(ScenarioSubElementType::CODE)->execute($_scenario); } public function executeFor(&$_scenario) { $for = $this->getSubElement(ScenarioElementType::FOR); if ($for->getOptions('enable', 1) == 0) { return true; } $limits = $for->getExpression(); $limits = intval(NextDomHelper::evaluateExpression($limits[0]->getExpression())); if (!is_numeric($limits)) { $_scenario->setLog(__('[ERREUR] La condition pour une boucle doit être numérique : ') . $limits); throw new CoreException(__('La condition pour une boucle doit être numérique : ') . $limits); } $return = false; for ($i = 1; $i <= $limits; $i++) { $return = $this->getSubElement('do')->execute($_scenario); } return $return; } public function executeIn(&$_scenario) { $in = $this->getSubElement(ScenarioSubElementType::IN); if ($in->getOptions('enable', 1) == 0) { return true; } $time = ceil(str_replace('.', ',', NextDomHelper::evaluateExpression($in->getExpression()[0]->getExpression(), $_scenario))); if (!is_numeric($time) || $time < 0) { $time = 0; } if ($time == 0) { $cmd = NEXTDOM_ROOT . '/src/Api/start_scenario.php '; $cmd .= ' scenario_id=' . $_scenario->getId(); $cmd .= ' scenarioElement_id=' . $this->getId(); $cmd .= ' tags=' . escapeshellarg(json_encode($_scenario->getTags())); $cmd .= ' >> ' . LogHelper::getPathToLog('scenario_element_execution') . ' 2>&1 &'; $_scenario->setLog(__('Tâche : ') . $this->getId() . __(' lancement immédiat ')); SystemHelper::php($cmd); } else { $crons = CronManager::searchClassAndFunction('scenario', 'doIn', '"scenarioElement_id":' . $this->getId() . ','); if (is_array($crons)) { foreach ($crons as $cron) { if ($cron->getState() != 'run') { $cron->remove(); } } } $cron = new cron(); $cron->setClass(NextDomObj::SCENARIO); $cron->setFunction('doIn'); $cron->setOption(['scenario_id' => intval($_scenario->getId()), 'scenarioElement_id' => intval($this->getId()), 'second' => date('s'), 'tags' => $_scenario->getTags()]); $cron->setLastRun(date(DateFormat::FULL)); $cron->setOnce(1); $next = strtotime('+ ' . $time . ' min'); $cron->setSchedule(CronManager::convertDateToCron($next)); $cron->save(); $_scenario->setLog(__('Tâche : ') . $this->getId() . __(' programmé à : ') . date(DateFormat::FULL, $next) . ' (+ ' . $time . ' min)'); } return true; } public function executeAt(&$_scenario) { $at = $this->getSubElement(ScenarioSubElementType::AT); if ($at->getOptions('enable', 1) == 0) { return true; } $next = NextDomHelper::evaluateExpression($at->getExpression()[0]->getExpression(), $_scenario); if (!is_numeric($next) || $next < 0) { throw new CoreException(__('Bloc type A : ') . $this->getId() . __(', heure programmée invalide : ') . $next); } if ($next <= date('Gi')) { $next = str_repeat('0', 4 - strlen($next)) . $next; $next = date(DateFormat::FULL_DAY, strtotime('+1 day' . date(DateFormat::FULL_DAY))) . ' ' . substr($next, 0, 2) . ':' . substr($next, 2, 4); } else { $next = str_repeat('0', 4 - strlen($next)) . $next; $next = date(DateFormat::FULL_DAY) . ' ' . substr($next, 0, 2) . ':' . substr($next, 2, 4); } $next = strtotime($next); if ($next < strtotime(DateFormat::NOW)) { throw new CoreException(__('Bloc type A : ') . $this->getId() . __(', heure programmée invalide : ') . date('Y-m-d H:i:00', $next)); } $crons = CronManager::searchClassAndFunction('scenario', 'doIn', '"scenarioElement_id":' . $this->getId() . ','); if (is_array($crons)) { foreach ($crons as $cron) { if ($cron->getState() != 'run') { $cron->remove(); } } } $cron = new Cron(); $cron->setClass(NextDomObj::SCENARIO); $cron->setFunction('doIn'); $cron->setOption(['scenario_id' => intval($_scenario->getId()), 'scenarioElement_id' => intval($this->getId()), 'second' => 0, 'tags' => $_scenario->getTags()]); $cron->setLastRun(date(DateFormat::FULL, strtotime('now'))); $cron->setOnce(1); $cron->setSchedule(CronManager::convertDateToCron($next)); $cron->save(); $_scenario->setLog(__('Tâche : ') . $this->getId() . __(' programmée à : ') . date('Y-m-d H:i:00', $next)); return true; } /** * @param Scenario|null $_scenario * @return bool|null * @throws CoreException * @throws \ReflectionException */ public function execute(&$_scenario = null) { if ($_scenario != null && !$_scenario->getDo()) { return null; } if (!is_object($this->getSubElement($this->getType()))) { return null; } switch ($this->getType()) { case ScenarioElementType::IF: return $this->executeIf($_scenario); case ScenarioElementType::ACTION: return $this->executeAction($_scenario); case ScenarioElementType::CODE: return $this->executeCode($_scenario); case ScenarioElementType::FOR: return $this->executeFor($_scenario); case ScenarioElementType::IN: return $this->executeIn($_scenario); case ScenarioElementType::AT: return $this->executeAt($_scenario); } return null; } /** * @param string $_mode * @return array * @throws \ReflectionException */ public function getAjaxElement($_mode = 'ajax') { $return = Utils::o2a($this); if ($_mode == 'array') { if (isset($return['id'])) { unset($return['id']); } if (isset($return['scenarioElement_id'])) { unset($return['scenarioElement_id']); } if (isset($return['log'])) { unset($return['log']); } if (isset($return['_expression'])) { unset($return['_expression']); } } $return['subElements'] = []; foreach ($this->getSubElement() as $subElement) { $subElement_ajax = Utils::o2a($subElement); if ($_mode == 'array') { if (isset($subElement_ajax['id'])) { unset($subElement_ajax['id']); } if (isset($subElement_ajax['scenarioElement_id'])) { unset($subElement_ajax['scenarioElement_id']); } if (isset($subElement_ajax['log'])) { unset($subElement_ajax['log']); } if (isset($subElement_ajax['_expression'])) { unset($subElement_ajax['_expression']); } } $subElement_ajax['expressions'] = []; foreach ($subElement->getExpression() as $expression) { $expression_ajax = Utils::o2a($expression); if ($_mode == 'array') { if (isset($expression_ajax['id'])) { unset($expression_ajax['id']); } if (isset($expression_ajax['scenarioSubElement_id'])) { unset($expression_ajax['scenarioSubElement_id']); } if (isset($expression_ajax['log'])) { unset($expression_ajax['log']); } if (isset($expression_ajax['_expression'])) { unset($expression_ajax['_expression']); } } if ($expression->getType() == ScenarioExpressionType::ELEMENT) { $element = ScenarioElementManager::byId($expression->getExpression()); if (is_object($element)) { $expression_ajax['element'] = $element->getAjaxElement($_mode); if ($_mode == 'array') { if (isset($expression_ajax['element']['id'])) { unset($expression_ajax['element']['id']); } if (isset($expression_ajax['element']['scenarioElement_id'])) { unset($expression_ajax['element']['scenarioElement_id']); } if (isset($expression_ajax['element']['log'])) { unset($expression_ajax['element']['log']); } if (isset($expression_ajax['element']['_expression'])) { unset($expression_ajax['element']['_expression']); } } } } $expression_ajax = NextDomHelper::toHumanReadable($expression_ajax); $subElement_ajax['expressions'][] = $expression_ajax; } $return['subElements'][] = $subElement_ajax; } return $return; } /** * @return array * @throws \Exception */ public function getAllId() { $return = [ 'element' => [$this->getId()], 'subelement' => [], 'expression' => [], ]; foreach ($this->getSubElement() as $subelement) { $result = $subelement->getAllId(); $return['element'] = array_merge($return['element'], $result['element']); $return['subelement'] = array_merge($return['subelement'], $result['subelement']); $return['expression'] = array_merge($return['expression'], $result['expression']); } return $return; } public function resetRepeatIfStatus() { foreach ($this->getSubElement() as $subElement) { if ($subElement->getType() == 'if') { $subElement->setOptions('previousState', -1); $subElement->save(); } foreach ($subElement->getExpression() as $expression) { $expression->resetRepeatIfStatus(); } } } /** * @return string * @throws \Exception */ public function export() { $return = ''; foreach ($this->getSubElement() as $subElement) { $return .= "\n"; switch ($subElement->getType()) { case ScenarioElementType::IF: $return .= __('SI'); break; case ScenarioElementType::THEN: $return .= __('ALORS'); break; case ScenarioElementType::ELSE: $return .= __('SINON'); break; case ScenarioElementType::FOR: $return .= __('POUR'); break; case ScenarioElementType::DO: $return .= __('FAIRE'); break; case ScenarioElementType::CODE: $return .= __('CODE'); break; case ScenarioElementType::ACTION: $return .= __('ACTION'); break; case ScenarioElementType::IN: $return .= __('DANS'); break; case ScenarioElementType::AT: $return .= __('A'); break; default: $return .= $subElement->getType(); break; } foreach ($subElement->getExpression() as $expression) { $export = $expression->export(); if ($expression->getType() != 'condition' && trim($export) != '') { $return .= "\n"; } if (trim($export) != '') { $return .= ' ' . $expression->export(); } } } return $return; } /** * @return int * @throws \Exception */ public function copy() { $elementCopy = clone $this; $elementCopy->setId(''); $elementCopy->save(); foreach ($this->getSubElement() as $subelement) { $subelement->copy($elementCopy->getId()); } return $elementCopy->getId(); } /** * @return mixed|null * @throws \Exception */ public function getScenario() { $scenario = ScenarioManager::byElement($this->getId()); if (is_object($scenario)) { return $scenario; } $expression = ScenarioExpressionManager::byElement($this->getId()); if (is_object($expression)) { return $expression->getSubElement()->getElement()->getScenario(); } return null; } } |