Source of file CronManager.php

Size: 7,296 Bytes - Last Modified: 2020-10-24T02:46:31+00:00

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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
<?php
/*
* This file is part of the NextDom software (https://github.com/NextDom or http://nextdom.github.io).
* Copyright (c) 2018 NextDom.
*
* This program 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, version 2.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/

/* 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\Managers;

use NextDom\Helpers\DBHelper;
use NextDom\Helpers\NextDomHelper;
use NextDom\Helpers\SystemHelper;
use NextDom\Managers\Parents\BaseManager;
use NextDom\Managers\Parents\CommonManager;
use NextDom\Model\Entity\Cron;

/**
 * Class CronManager
 * @package NextDom\Managers
 */
class CronManager extends BaseManager
{
    use CommonManager;

    const CLASS_NAME = Cron::class;
    const DB_CLASS_NAME = '`cron`';

    /**
     * Return cron object by class and function
     *
     * @param string $className Name of the class
     * @param string $functionName Name of the method
     * @param string $options Filter options
     *
     * @return Cron Cron object
     * @throws \Exception
     */
    public static function byClassAndFunction($className, $functionName, $options = '')
    {
        $value = [
            'class' => $className,
            'function' => $functionName,
        ];
        $sql = static::getBaseSQL() . '
                WHERE `class` = :class
                AND `function` = :function';
        if ($options != '') {
            $options = json_encode($options, JSON_UNESCAPED_UNICODE);
            $value['option'] = $options;
            $sql .= ' AND `option` = :option';
        }
        return DBHelper::getOneObject($sql, $value, self::CLASS_NAME);
    }

    /**
     * Return cron object by class and function
     *
     * @param string $className Name of the class
     * @param string $functionName Name of the method
     * @param string $options Filter options
     *
     * @return Cron[] List of cron objects
     * @throws \Exception
     */
    public static function searchClassAndFunction($className, $functionName, $options = '')
    {
        $value = [
            'class' => $className,
            'function' => $functionName,
        ];
        $sql = static::getBaseSQL() . '
                WHERE `class` = :class
                AND `function` = :function';
        if ($options != '') {
            $value['option'] = '%' . $options . '%';
            $sql .= ' AND `option` LIKE :option';
        }
        return DBHelper::getAllObjects($sql, $value, self::CLASS_NAME);
    }

    /**
     * Clean cron that will never run
     * @throws \Exception
     */
    public static function clean()
    {
        $crons = self::all();
        foreach ($crons as $cron) {
            $cronExpression = new \Cron\CronExpression($cron->getSchedule(), new \Cron\FieldFactory());
            try {
                if (!$cronExpression->isDue()) {
                    $cronExpression->getNextRunDate();
                }
            } catch (\Exception $ex) {
                $cron->remove();
            }
        }
    }

    /**
     * Return an array of all cron objects
     *
     * @param bool $ordered
     * @return Cron[] List of all cron objets
     * @throws \Exception
     */
    public static function all($ordered = false)
    {
        if ($ordered) {
            return static::getAllOrdered('deamon', true);
        }
        else {
            return static::getAll();
        }
    }

    /**
     * Return number of running cron
     *
     * @return int Number of running cron
     */
    public static function nbCronRun()
    {
        return count(SystemHelper::ps('start_cron.php', ['grep', 'sudo', 'shell=/bin/bash - ', '/bin/bash -c ', posix_getppid(), getmypid()]));
    }

    /**
     * Return number of process on system
     *
     * @TODO: Move to other place ?
     *
     * @return int Number of process on system
     */
    public static function nbProcess()
    {
        return count(SystemHelper::ps('.'));
    }

    /**
     * Return array of load average
     *
     * @TODO: Inutile, autant appeler directement la fonction
     *
     * @return array Load average
     */
    public static function loadAvg()
    {
        return sys_getloadavg();
    }

    /**
     * Write jeeCron PID of current process
     * @throws \Exception
     */
    public static function setPidFile()
    {
        $path = NextDomHelper::getTmpFolder() . '/jeeCron.pid';
        $fp = fopen($path, 'w');
        fwrite($fp, getmypid());
        fclose($fp);
    }

    /**
     * Get status of jeeCron
     *
     * @return boolean True if jeeCron is running
     * @throws \Exception
     */
    public static function jeeCronRun()
    {
        $pid = self::getPidFile();
        if ($pid == '' || !is_numeric($pid)) {
            return false;
        }
        return posix_getsid($pid);
    }

    /**
     * Return the current pid of jeecron or empty if not running
     *
     * @return false|string Current jeeCron PID
     * @throws \Exception
     */
    public static function getPidFile()
    {
        $path = NextDomHelper::getTmpFolder() . '/jeeCron.pid';
        if (file_exists($path)) {
            return file_get_contents($path);
        }
        return '';
    }

    /**
     * Convert date to cron format.
     *
     * @param string $dateToConvert Date to convert
     *
     * @return string Date in cron format
     */
    public static function convertDateToCron($dateToConvert)
    {
        return date('i', $dateToConvert) . ' ' . date('H', $dateToConvert) . ' ' . date('d', $dateToConvert) . ' ' . date('m', $dateToConvert) . ' * ' . date('Y', $dateToConvert);
    }

    /**
     * convert cron schedule string
     *
     * @param string $cron F cron schedule format to re
     * @return string
     * @throws \Exception
     */
    public static function convertCronSchedule(string $cron)
    {
        $return = str_replace('*/ ', '* ', $cron);
        preg_match_all('/([0-9]*\/\*)/m', $return, $matches, PREG_SET_ORDER, 0);
        if (count($matches) > 0) {
            return '';
        }
        preg_match_all('/(\*\/0)/m', $return, $matches, PREG_SET_ORDER, 0);
        if (count($matches) > 0) {
            return '';
        }
        return $return;
    }
}