vendor/elements/process-manager-bundle/src/Model/MonitoringItem.php line 588

Open in your IDE?
  1. <?php
  2. /**
  3.  * Elements.at
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Enterprise License (PEL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) elements.at New Media Solutions GmbH (https://www.elements.at)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PEL
  13.  */
  14. namespace Elements\Bundle\ProcessManagerBundle\Model;
  15. use Elements\Bundle\ProcessManagerBundle\ElementsProcessManagerBundle;
  16. use Elements\Bundle\ProcessManagerBundle\Executor\Logger\AbstractLogger;
  17. use Elements\Bundle\ProcessManagerBundle\Message\CheckCommandAliveMessage;
  18. use Elements\Bundle\ProcessManagerBundle\Message\StopProcessMessage;
  19. use Monolog\Handler\StreamHandler;
  20. use Monolog\Logger;
  21. use Symfony\Component\Process\Process;
  22. use function Symfony\Component\Debug\Tests\testHeader;
  23. /**
  24.  * Class MonitoringItem
  25.  *
  26.  * @method  MonitoringItem save() MonitoringItem
  27.  * @method  MonitoringItem load() []MonitoringItem
  28.  */
  29. class MonitoringItem extends \Pimcore\Model\AbstractModel
  30. {
  31.     const STATUS_UNKNOWN 'unknown';
  32.     const STATUS_FINISHED 'finished';
  33.     const STATUS_FINISHED_WITH_ERROR 'finished_with_errors';
  34.     const STATUS_FAILED 'failed';
  35.     const STATUS_RUNNING 'running';
  36.     const STATUS_INITIALIZING 'initializing';
  37.     /**
  38.      * @var int
  39.      */
  40.     public $id;
  41.     /**
  42.      * @var int
  43.      */
  44.     public $parentId;
  45.     public $name;
  46.     public $message;
  47.     public $status self::STATUS_UNKNOWN;
  48.     public $command;
  49.     public $creationDate;
  50.     public $configurationId;
  51.     public $reportedDate;
  52.     public $modificationDate;
  53.     public $pid;
  54.     public $loggers = [];
  55.     /**
  56.      * @var array
  57.      */
  58.     public $actions = [];
  59.     /**
  60.      * @var int
  61.      */
  62.     public $executedByUser 0;
  63.     /**
  64.      * @var \Monolog\Logger
  65.      */
  66.     protected $logger;
  67.     /**
  68.      * @var array
  69.      */
  70.     public $callbackSettings = [];
  71.     /**
  72.      * @var int
  73.      */
  74.     public $totalWorkload;
  75.     /**
  76.      * @var int
  77.      */
  78.     public $currentWorkload;
  79.     /**
  80.      * @var int
  81.      */
  82.     public $currentStep 0;
  83.     /**
  84.      * @var int
  85.      */
  86.     public $totalSteps 1;
  87.     /**
  88.      * The dummy object won't be saved
  89.      * It is just created when no monitoring item id is passed
  90.      * so we dont have to check if the monitoring item is available
  91.      *
  92.      * @var bool
  93.      */
  94.     public $isDummy false;
  95.     /**
  96.      * @var bool
  97.      */
  98.     public $published true;
  99.     public $messengerPending false;
  100.     /**
  101.      * @var string
  102.      */
  103.     public $group '';
  104.     /**
  105.      * @var int | null
  106.      */
  107.     public $deleteAfterHours null;
  108.     /**
  109.      * @var string
  110.      */
  111.     public $metaData '';
  112.     public $hasCriticalError false;
  113.     /**
  114.      * Error Level which sould be considered as critical
  115.      * ['critical','error','emergency']...
  116.      *
  117.      * @var array
  118.      */
  119.     public $criticalErrorLevel = [];
  120.     /**
  121.      * @return array
  122.      */
  123.     public function getCriticalErrorLevel(): array
  124.     {
  125.         return $this->criticalErrorLevel;
  126.     }
  127.     /**
  128.      * @param array $criticalErrorLevel
  129.      * @return $this
  130.      */
  131.     public function setCriticalErrorLevel($criticalErrorLevel)
  132.     {
  133.         $this->criticalErrorLevel $criticalErrorLevel;
  134.         return $this;
  135.     }
  136.     /**
  137.      * @return int
  138.      */
  139.     public function getDeleteAfterHours()
  140.     {
  141.         return $this->deleteAfterHours;
  142.     }
  143.     /**
  144.      * @param int $deleteAfterHours
  145.      * @return $this
  146.      */
  147.     public function setDeleteAfterHours($deleteAfterHours)
  148.     {
  149.         $this->deleteAfterHours $deleteAfterHours;
  150.         return $this;
  151.     }
  152.     /**
  153.      * @return bool
  154.      */
  155.     public function getHasCriticalError(): bool
  156.     {
  157.         return $this->hasCriticalError;
  158.     }
  159.     /**
  160.      * @return int
  161.      */
  162.     public function getParentId()
  163.     {
  164.         return $this->parentId;
  165.     }
  166.     /**
  167.      * @param int $parentId
  168.      * @return $this
  169.      */
  170.     public function setParentId($parentId)
  171.     {
  172.         $this->parentId $parentId;
  173.         return $this;
  174.     }
  175.     /**
  176.      * @param bool $hasCriticalError
  177.      * @return $this
  178.      */
  179.     public function setHasCriticalError($hasCriticalError)
  180.     {
  181.         $this->hasCriticalError $hasCriticalError;
  182.         return $this;
  183.     }
  184.     /**
  185.      * @return string
  186.      */
  187.     public function getMetaData()
  188.     {
  189.         return $this->metaData;
  190.     }
  191.     /**
  192.      * @param string $metaData
  193.      *
  194.      * @return $this
  195.      */
  196.     public function setMetaData($metaData)
  197.     {
  198.         $this->metaData $metaData;
  199.         return $this;
  200.     }
  201.     /**
  202.      * @return bool
  203.      */
  204.     public function isPublished()
  205.     {
  206.         return $this->published;
  207.     }
  208.     /**
  209.      * @param bool $published
  210.      *
  211.      * @return $this
  212.      */
  213.     public function setPublished($published)
  214.     {
  215.         $this->published $published;
  216.         return $this;
  217.     }
  218.     /**
  219.      * @return bool
  220.      */
  221.     public function isMessengerPending(): bool
  222.     {
  223.         return $this->messengerPending;
  224.     }
  225.     /**
  226.      * @param bool $messengerPending
  227.      * @return MonitoringItem
  228.      */
  229.     public function setMessengerPending(bool $messengerPending): MonitoringItem
  230.     {
  231.         $this->messengerPending $messengerPending;
  232.         return $this;
  233.     }
  234.     /**
  235.      * @return string
  236.      */
  237.     public function getGroup()
  238.     {
  239.         return $this->group;
  240.     }
  241.     /**
  242.      * @param string $group
  243.      *
  244.      * @return $this
  245.      */
  246.     public function setGroup($group)
  247.     {
  248.         $this->group $group;
  249.         return $this;
  250.     }
  251.     /**
  252.      * @return bool
  253.      */
  254.     public function getIsDummy()
  255.     {
  256.         return $this->isDummy;
  257.     }
  258.     /**
  259.      * @param bool $isDummy
  260.      *
  261.      * @return $this
  262.      */
  263.     public function setIsDummy($isDummy)
  264.     {
  265.         $this->isDummy $isDummy;
  266.         return $this;
  267.     }
  268.     /**
  269.      * @param int $id
  270.      *
  271.      * @return self
  272.      */
  273.     public static function getById($id)
  274.     {
  275.         $self = new self();
  276.         return $self->getDao()->getById($id);
  277.     }
  278.     /**
  279.      * @return static
  280.      */
  281.     public function setValues($data = [])
  282.     {
  283.         if (is_array($data) && count($data) > 0) {
  284.             foreach ($data as $key => $value) {
  285.                 if ($key == 'message') {
  286.                     $this->setMessage($valuefalse);
  287.                 } else {
  288.                     $this->setValue($key$value);
  289.                 }
  290.             }
  291.         }
  292.         return $this;
  293.     }
  294.     /**
  295.      * @return array
  296.      */
  297.     public function getActions()
  298.     {
  299.         $actions $this->actions;
  300.         if (is_string($actions)) {
  301.             $actions json_decode($actionstrue);
  302.         }
  303.         return $actions;
  304.     }
  305.     /**
  306.      * @param array $actions
  307.      *
  308.      * @return $this
  309.      */
  310.     public function setActions($actions)
  311.     {
  312.         $this->actions $actions;
  313.         return $this;
  314.     }
  315.     /**
  316.      * @return int
  317.      */
  318.     public function getTotalWorkload()
  319.     {
  320.         return $this->totalWorkload;
  321.     }
  322.     /**
  323.      * @param int $totalWorkload
  324.      *
  325.      * @return $this
  326.      */
  327.     public function setTotalWorkload($totalWorkload)
  328.     {
  329.         $this->totalWorkload $totalWorkload;
  330.         return $this;
  331.     }
  332.     /**
  333.      * @return int
  334.      */
  335.     public function getCurrentWorkload()
  336.     {
  337.         return $this->currentWorkload;
  338.     }
  339.     /**
  340.      * @param int $currentWorkload
  341.      *
  342.      * @return $this
  343.      */
  344.     public function setCurrentWorkload($currentWorkload)
  345.     {
  346.         $this->currentWorkload $currentWorkload;
  347.         return $this;
  348.     }
  349.     /**
  350.      * @return Configuration
  351.      */
  352.     public function getProcessManagerConfigObject()
  353.     {
  354.         if ($id $this->getConfigurationId()) {
  355.             $config Configuration::getById($id);
  356.             return $config;
  357.         }
  358.     }
  359.     /**
  360.      * @return int
  361.      */
  362.     public function getCurrentStep()
  363.     {
  364.         return $this->currentStep;
  365.     }
  366.     /**
  367.      * @param int $currentStep
  368.      *
  369.      * @return $this
  370.      */
  371.     public function setCurrentStep($currentStep)
  372.     {
  373.         $this->currentStep $currentStep;
  374.         return $this;
  375.     }
  376.     /**
  377.      * @return int
  378.      */
  379.     public function getTotalSteps()
  380.     {
  381.         return $this->totalSteps;
  382.     }
  383.     /**
  384.      * @param int $totalSteps
  385.      *
  386.      * @return $this
  387.      */
  388.     public function setTotalSteps($totalSteps)
  389.     {
  390.         $this->totalSteps $totalSteps;
  391.         return $this;
  392.     }
  393.     /**
  394.      * @param int $id
  395.      *
  396.      * @return $this
  397.      */
  398.     public function setId($id)
  399.     {
  400.         $this->id = (int)$id;
  401.         return $this;
  402.     }
  403.     /**
  404.      * @return int
  405.      */
  406.     public function getId()
  407.     {
  408.         return $this->id;
  409.     }
  410.     /**
  411.      * @param $name
  412.      *
  413.      * @return $this
  414.      */
  415.     public function setName($name)
  416.     {
  417.         $this->name $name;
  418.         return $this;
  419.     }
  420.     public function getName()
  421.     {
  422.         return $this->name;
  423.     }
  424.     /**
  425.      * @param mixed $message
  426.      *
  427.      * @return $this
  428.      */
  429.     public function setMessage($message$logLevel \Monolog\Logger::NOTICE)
  430.     {
  431.         $this->message $message;
  432.         if ($logLevel !== false) {
  433.             $this->getLogger()->log($logLevel$message);
  434.         }
  435.         return $this;
  436.     }
  437.     /**
  438.      * @return mixed
  439.      */
  440.     public function getMessage()
  441.     {
  442.         return $this->message;
  443.     }
  444.     /**
  445.      * @param $status
  446.      *
  447.      * @return $this
  448.      */
  449.     public function setStatus($status)
  450.     {
  451.         $this->status $status;
  452.         return $this;
  453.     }
  454.     /**
  455.      * @return mixed
  456.      */
  457.     public function getStatus()
  458.     {
  459.         return $this->status;
  460.     }
  461.     /**
  462.      * @param mixed $command
  463.      *
  464.      * @return $this
  465.      */
  466.     public function setCommand($command)
  467.     {
  468.         $this->command $command;
  469.         return $this;
  470.     }
  471.     /**
  472.      * @return mixed
  473.      */
  474.     public function getCommand()
  475.     {
  476.         return $this->command;
  477.     }
  478.     /** Returns true if the item died unexpectetly
  479.      * @return bool
  480.      */
  481.     public function isAlive()
  482.     {
  483.         if($this->isMessengerPending()) {
  484.             return true;
  485.         }
  486.         if ($this->getPid()) {
  487.             $messageBus \Pimcore::getContainer()->get('messenger.bus.pimcore-core');
  488.             $message = new CheckCommandAliveMessage($this->getId());
  489.             $messageBus->dispatch($message);
  490.             return (bool)self::getById($this->getId())->getPid();
  491.         }else{
  492.             return false;
  493.         }
  494.     }
  495.     /**
  496.      * @return mixed
  497.      */
  498.     public function getCreationDate()
  499.     {
  500.         return $this->creationDate;
  501.     }
  502.     /**
  503.      * @param mixed $creationDate
  504.      */
  505.     public function setCreationDate($creationDate)
  506.     {
  507.         $this->creationDate $creationDate;
  508.         return $this;
  509.     }
  510.     /**
  511.      * @return mixed
  512.      */
  513.     public function getModificationDate()
  514.     {
  515.         return $this->modificationDate;
  516.     }
  517.     /**
  518.      * @param mixed $modificationDate
  519.      */
  520.     public function setModificationDate($modificationDate)
  521.     {
  522.         $this->modificationDate $modificationDate;
  523.         return $this;
  524.     }
  525.     /**
  526.      * convenience function to set the process message
  527.      *
  528.      * @param string $itemType
  529.      * @param int $logLevel
  530.      *
  531.      * @return $this
  532.      */
  533.     public function setDefaultProcessMessage($itemType 'item'$logLevel Logger::NOTICE)
  534.     {
  535.         $currentWorkload $this->getCurrentWorkload() ?: 1;
  536.         $this->setMessage(
  537.             'Processing '.$itemType.' '.$currentWorkload.' from '.$this->getTotalWorkload(
  538.             ).' ('.($this->getTotalWorkload() - $currentWorkload).' remaining)',
  539.             $logLevel
  540.         );
  541.         return $this;
  542.     }
  543.     /**
  544.      * @return $this
  545.      */
  546.     public function resetWorkload()
  547.     {
  548.         $this->setCurrentWorkload(0);
  549.         $this->setTotalWorkload(0);
  550.         return $this;
  551.     }
  552.     /**
  553.      * @deprecated Use setWorkloadCompleted() instead
  554.      * @return $this
  555.      */
  556.     public function setWorloadCompleted()
  557.     {
  558.         return $this->setWorkloadCompleted();
  559.     }
  560.     /**
  561.      * @return $this
  562.      */
  563.     public function setWorkloadCompleted()
  564.     {
  565.         $this->setCurrentWorkload($this->getTotalWorkload());
  566.         return $this;
  567.     }
  568.     public function getDuration()
  569.     {
  570.         $took $this->getModificationDate() - $this->getCreationDate();
  571.         if ($took 0) {
  572.             if ($took 60) {
  573.                 return $took.'s';
  574.             }
  575.             if ($took 3600) {
  576.                 $minutes floor($took 60);
  577.                 $seconds $took - ($minutes 60);
  578.                 return $minutes.'m '.$seconds.'s';
  579.             }
  580.             return gmdate('h'$took).'h '.gmdate('i'$took).'m '.gmdate('s'$took).'s';
  581.         }
  582.     }
  583.     /**
  584.      * @return mixed
  585.      */
  586.     public function getConfigurationId()
  587.     {
  588.         return $this->configurationId;
  589.     }
  590.     /**
  591.      * @param mixed $configurationId
  592.      *
  593.      * @return $this
  594.      */
  595.     public function setConfigurationId($configurationId)
  596.     {
  597.         $this->configurationId $configurationId;
  598.         return $this;
  599.     }
  600.     /**
  601.      * @return mixed
  602.      */
  603.     public function getPid()
  604.     {
  605.         return $this->pid;
  606.     }
  607.     /**
  608.      * @param mixed $pid
  609.      *
  610.      * @return $this
  611.      */
  612.     public function setPid($pid)
  613.     {
  614.         $this->pid $pid;
  615.         return $this;
  616.     }
  617.     public function getLogFile()
  618.     {
  619.         return ElementsProcessManagerBundle::getLogDir().$this->getId().'.log';
  620.     }
  621.     /**
  622.      * @return $this
  623.      */
  624.     public function deleteLogFile()
  625.     {
  626.         if (is_file($this->getLogFile())) {
  627.             unlink($this->getLogFile());
  628.         }
  629.         return $this;
  630.     }
  631.     /**
  632.      * @return $this
  633.      */
  634.     public function resetState()
  635.     {
  636.         $this->setStatus(self::STATUS_UNKNOWN);
  637.         $this->resetWorkload();
  638.         $this->setCurrentStep(0)->setTotalSteps(0)->setPid(null);
  639.         $this->setMessage(''false);
  640.         $this->setCreationDate(time());
  641.         $this->setModificationDate(time());
  642.         $this->setHasCriticalError(0);
  643.         return $this;
  644.     }
  645.     public function setCompleted()
  646.     {
  647.         $this->setWorkloadCompleted();
  648.         $this->setCurrentStep($this->getTotalSteps());
  649.         //do not change the state if set it to failed - otherwise it would appear to be successfully finished
  650.         if ($this->getStatus() != self::STATUS_FAILED) {
  651.             $this->setStatus($this->getHasCriticalError() ? self::STATUS_FINISHED_WITH_ERROR self::STATUS_FINISHED);
  652.         }
  653.         $this->save();
  654.     }
  655.     /**
  656.      * @return array
  657.      */
  658.     public function getCallbackSettings()
  659.     {
  660.         return is_string($this->callbackSettings) ? json_decode($this->callbackSettingstrue) : $this->callbackSettings;
  661.     }
  662.     public function getCallbackSettingsForGrid()
  663.     {
  664.         $html '';
  665.         $data $this->getCallbackSettings();
  666.         if (!empty($data)) {
  667.             $html .= '<table class="process-manager-callback-settings-table"><tr><th>Key</th><th>Value</th></tr>';
  668.             foreach ($data as $key => $value) {
  669.                 $html .= '<tr><td>'.$key.'</td><td>';
  670.                 if (is_array($value)) {
  671.                     $html .= '<pre>'.print_r($valuetrue).'</pre>';
  672.                 } else {
  673.                     $html .= $value;
  674.                 }
  675.                 $html .= '</td></tr>';
  676.             }
  677.             $html .= '</table>';
  678.         }
  679.         return $html;
  680.     }
  681.     /**
  682.      * @param array $callbackSettings
  683.      *
  684.      * @return $this
  685.      */
  686.     public function setCallbackSettings($callbackSettings)
  687.     {
  688.         $this->callbackSettings $callbackSettings;
  689.         return $this;
  690.     }
  691.     /**
  692.      * Shorthand to get the values
  693.      *
  694.      * @return array
  695.      */
  696.     public function getConfigValues()
  697.     {
  698.         return $this->getProcessManagerConfigObject()->getExecutorClassObject()->getValues();
  699.     }
  700.     public function getReportValues()
  701.     {
  702.         $data = [];
  703.         foreach (['id''pid''name''command''creationDate''modificationDate''callbackSettings'] as $field) {
  704.             $data[$field] = $this->{'get'.ucfirst($field)}();
  705.         }
  706.         return $data;
  707.     }
  708.     /**
  709.      * @return mixed
  710.      */
  711.     public function getReportedDate()
  712.     {
  713.         return $this->reportedDate;
  714.     }
  715.     /**
  716.      * @param mixed $reportedDate
  717.      *
  718.      * @return $this
  719.      */
  720.     public function setReportedDate($reportedDate)
  721.     {
  722.         $this->reportedDate $reportedDate;
  723.         return $this;
  724.     }
  725.     /**
  726.      * @return \Pimcore\Log\ApplicationLogger
  727.      */
  728.     public function getLogger()
  729.     {
  730.         if (!$this->logger) {
  731.             $this->logger = new \Elements\Bundle\ProcessManagerBundle\Logger();
  732.             $this->logger->setComponent($this->getName());
  733.             if ($loggerData $this->getLoggers()) {
  734.                 foreach ($loggerData as $loggerConfig) {
  735.                     /**
  736.                      * @var AbstractLogger $obj
  737.                      */
  738.                     $class $loggerConfig['class'];
  739.                     if (\Pimcore\Tool::classExists($class)) {
  740.                         $obj = new $class();
  741.                         $streamHandler $obj->createStreamHandler($loggerConfig$this);
  742.                         if ($streamHandler) {
  743.                             $this->logger->addWriter($streamHandler);
  744.                         }
  745.                     }
  746.                 }
  747.             }
  748.         }
  749.         return $this->logger;
  750.     }
  751.     /**
  752.      * @return int
  753.      */
  754.     public function getExecutedByUser()
  755.     {
  756.         return (int)$this->executedByUser;
  757.     }
  758.     /**
  759.      * @param int $executedByUser
  760.      *
  761.      * @return $this
  762.      */
  763.     public function setExecutedByUser($executedByUser)
  764.     {
  765.         $this->executedByUser = (int)$executedByUser;
  766.         return $this;
  767.     }
  768.     /**
  769.      * @return array
  770.      */
  771.     public function getLoggers()
  772.     {
  773.         $loggers $this->loggers;
  774.         if (is_string($loggers)) {
  775.             $loggers json_decode($loggerstrue);
  776.         }
  777.         return $loggers;
  778.     }
  779.     /**
  780.      * @param array $loggers
  781.      *
  782.      * @return $this
  783.      */
  784.     public function setLoggers($loggers)
  785.     {
  786.         $this->loggers $loggers;
  787.         return $this;
  788.     }
  789.     public function getForWebserviceExport()
  790.     {
  791.         $data $this->getObjectVars();
  792.         $data['callbackSettings'] = json_decode($data['callbackSettings'], true);
  793.         $data['actions'] = json_decode($data['actions'], true);
  794.         $data['loggers'] = json_decode($data['loggers'], true);
  795.         unset($data['command']);
  796.         return $data;
  797.     }
  798.     /**
  799.      * @return int|null
  800.      */
  801.     public function getProgressPercentage()
  802.     {
  803.         if ($this->getCurrentWorkload() && $this->getTotalWorkload()) {
  804.             return round($this->getCurrentWorkload() / ($this->getTotalWorkload() / 100));
  805.         }
  806.         return null;
  807.     }
  808.     public function stopProcess(){
  809.         $pid $this->getPid();
  810.         if($pid){
  811.             $messageBus \Pimcore::getContainer()->get('messenger.bus.pimcore-core');
  812.             $message = new StopProcessMessage($this->getId());
  813.             $messageBus->dispatch($message);
  814.             return true;
  815.         }
  816.     }
  817.     public function getChildProcesses(){
  818.         $list = new MonitoringItem\Listing();
  819.         $list->setCondition('parentId = ?',[$this->getId()]);
  820.         $list->setOrder('id');
  821.         return $list->load();
  822.     }
  823.     public function getChildProcessesStatus(){
  824.         $summary = ['active' => 0'failed' => 0,'finished' => 0];
  825.         $details = ['active' => [], 'failed' => [],'finished' => []];
  826.         $currentWorkload 0;
  827.         foreach($this->getChildProcesses() as $child){
  828.             $details[$child->getStatus()][] = ['id' => $child->getId(),'message' => $child->getMessage(),'alive' => $child->isAlive()];
  829.             $currentWorkload += $child->getCurrentWorkload();
  830.             if($child->getStatus() == self::STATUS_FINISHED){
  831.                 $summary['finished']++;
  832.             }else{
  833.                 if($child->isAlive()){
  834.                     $summary['active']++;
  835.                 }else{
  836.                     $summary['failed']++;
  837.                 }
  838.             }
  839.         }
  840.         return [
  841.             'summary' => $summary,
  842.             'details' => $details,
  843.             'currentWorkload' => $currentWorkload,
  844.         ];
  845.     }
  846. }