Skip to content
Code-Schnipsel Gruppen Projekte
Manager.php 14,4 KiB
Newer Older
Henning Leutz's avatar
Henning Leutz committed
<?php

/**
 * This File contains QUI\Cron\Manager
 */

namespace QUI\Cron;

Henning Leutz's avatar
Henning Leutz committed
use QUI;
use QUI\Permissions\Permission;
Henning Leutz's avatar
Henning Leutz committed
use Cron\CronExpression;

Henning Leutz's avatar
Henning Leutz committed
/**
 * Cron Manager
 *
 * @author www.pcsg.de (Henning Leutz)
Henning Leutz's avatar
Henning Leutz committed
 * @error  1001 - Cannot add Cron. Cron not exists
 * @error  1002 - Cannot edit Cron. Cron command not exists
Henning Leutz's avatar
Henning Leutz committed
 */
class Manager
{
Henning Leutz's avatar
Henning Leutz committed
    /**
     * Add a cron
Henning Leutz's avatar
Henning Leutz committed
     *
Henning Leutz's avatar
Henning Leutz committed
     * @param string $cron - Name of the Cron
     * @param string $min - On which minute should it start
     * @param string $hour - On which hour should it start
     * @param string $day - On which day should it start
     * @param string $month - On which month should it start
     * @param string $dayOfWeek - day of week (0 - 6) (0 to 6 are Sunday to Saturday,
     *        or use names; 7 is Sunday, the same as 0)
     * @param array $params - Cron Parameter
Henning Leutz's avatar
Henning Leutz committed
     *
Henning Leutz's avatar
Henning Leutz committed
     * @throws QUI\Exception
Henning Leutz's avatar
Henning Leutz committed
     */
    public function add($cron, $min, $hour, $day, $month, $dayOfWeek, $params = array())
Henning Leutz's avatar
Henning Leutz committed
    {
Henning Leutz's avatar
Henning Leutz committed
        Permission::checkPermission('quiqqer.cron.add');
Henning Leutz's avatar
Henning Leutz committed
        if (!$this->cronExists($cron)) {
Henning Leutz's avatar
Henning Leutz committed
            throw new QUI\Exception(
Henning Leutz's avatar
Henning Leutz committed
                QUI::getLocale()->get('quiqqer/cron', 'exception.cron.1001'),
Henning Leutz's avatar
Henning Leutz committed
                1001
            );
Henning Leutz's avatar
Henning Leutz committed
        $cronData = $this->getCronData($cron);
Henning Leutz's avatar
Henning Leutz committed
        if (!is_array($params)) {
Henning Leutz's avatar
Henning Leutz committed
            $params = array();
        }

        QUI::getDataBase()->insert($this->table(), array(
            'active'    => 1,
            'exec'      => $cronData['exec'],
            'title'     => $cronData['title'],
            'min'       => $min,
            'hour'      => $hour,
            'day'       => $day,
            'month'     => $month,
            'dayOfWeek' => $dayOfWeek,
            'params'    => json_encode($params)
Henning Leutz's avatar
Henning Leutz committed
        ));

Henning Leutz's avatar
Henning Leutz committed
        QUI::getMessagesHandler()->addSuccess(
            QUI::getLocale()->get(
                'quiqqer/cron',
                'message.cron.succesful.added'
            )
Henning Leutz's avatar
Henning Leutz committed
    /**
     * Edit the cron
     *
Henning Leutz's avatar
Henning Leutz committed
     * @param string $cron - Name of the Cron
     * @param integer $cronId
     * @param string $min
     * @param string $hour
     * @param string $day
     * @param string $month
     * @param string $dayOfWeek
     * @param array $params
Henning Leutz's avatar
Henning Leutz committed
     *
Henning Leutz's avatar
Henning Leutz committed
     * @throws QUI\Exception
Henning Leutz's avatar
Henning Leutz committed
    public function edit(
        $cronId,
        $cron,
        $min,
        $hour,
        $day,
        $month,
Henning Leutz's avatar
Henning Leutz committed
        $params = array()
    ) {
        Permission::checkPermission('quiqqer.cron.edit');

Henning Leutz's avatar
Henning Leutz committed
        if (!$this->cronExists($cron)) {
Henning Leutz's avatar
Henning Leutz committed
            throw new QUI\Exception(
Henning Leutz's avatar
Henning Leutz committed
                QUI::getLocale()->get('quiqqer/cron', 'exception.cron.1002'),
Henning Leutz's avatar
Henning Leutz committed
                1002
            );
Henning Leutz's avatar
Henning Leutz committed
        $cronData = $this->getCronData($cron);
        // test the cron data
Henning Leutz's avatar
Henning Leutz committed
        try {
            CronExpression::factory(
                "$min $hour $day $month $dayOfWeek"
Henning Leutz's avatar
Henning Leutz committed
        } catch (\Exception $Exception) {
            throw new QUI\Exception($Exception->getMessage());
        QUI::getDataBase()->update($this->table(), array(
            'exec'      => $cronData['exec'],
            'title'     => $cronData['title'],
            'min'       => $min,
            'hour'      => $hour,
            'day'       => $day,
            'month'     => $month,
            'dayOfWeek' => $dayOfWeek,
            'params'    => json_encode($params)
Henning Leutz's avatar
Henning Leutz committed
        ), array(
            'id' => $cronId
        ));

Henning Leutz's avatar
Henning Leutz committed
        QUI::getMessagesHandler()->addSuccess(
            QUI::getLocale()->get(
                'quiqqer/cron',
                'message.cron.succesful.edit'
            )
    /**
     * activate a cron in the cron list
Henning Leutz's avatar
Henning Leutz committed
     *
Henning Leutz's avatar
Henning Leutz committed
     * @param integer $cronId - ID of the cron
     */
    public function activateCron($cronId)
    {
Henning Leutz's avatar
Henning Leutz committed
        Permission::checkPermission('quiqqer.cron.deactivate');
Henning Leutz's avatar
Henning Leutz committed
        QUI::getDataBase()->update(
            $this->table(),
            array('active' => 1),
            array('id' => (int)$cronId)
        );
    }

    /**
     * deactivate a cron in the cron list
Henning Leutz's avatar
Henning Leutz committed
     *
Henning Leutz's avatar
Henning Leutz committed
     * @param integer $cronId - ID of the cron
     */
    public function deactivateCron($cronId)
    {
Henning Leutz's avatar
Henning Leutz committed
        Permission::checkPermission('quiqqer.cron.activate');
Henning Leutz's avatar
Henning Leutz committed
        QUI::getDataBase()->update(
            $this->table(),
            array('active' => 0),
            array('id' => (int)$cronId)
        );
    }

Henning Leutz's avatar
Henning Leutz committed
     *
Henning Leutz's avatar
Henning Leutz committed
     * @param array $ids - Array of the Cron-Ids
Henning Leutz's avatar
Henning Leutz committed
        Permission::checkPermission('quiqqer.cron.delete');
Henning Leutz's avatar
Henning Leutz committed
        $DataBase = QUI::getDataBase();
Henning Leutz's avatar
Henning Leutz committed
        foreach ($ids as $id) {
Henning Leutz's avatar
Henning Leutz committed
            if ($this->getCronById($id) === false) {
            $DataBase->delete($this->table(), array(
                'id' => $id
            ));
        }
    }

    /**
     * Execute all upcoming crons
     */
    public function execute()
    {
Henning Leutz's avatar
Henning Leutz committed
        Permission::checkPermission('quiqqer.cron.execute');
Henning Leutz's avatar
Henning Leutz committed
        foreach ($list as $entry) {
            if ($entry['active'] != 1) {
            $min       = $entry['min'];
            $hour      = $entry['hour'];
            $day       = $entry['day'];
            $month     = $entry['month'];
            $dayOfWeek = '*';

            if (isset($entry['dayOfMonth']) && !empty($entry['dayOfMonth'])) {
                $dayOfWeek = $entry['dayOfMonth'];
            }

Henning Leutz's avatar
Henning Leutz committed
            $Cron = CronExpression::factory(
                "$min $hour $day $month $dayOfWeek"
Henning Leutz's avatar
Henning Leutz committed
            $next = $Cron->getNextRunDate($lastexec)->getTimestamp();
Henning Leutz's avatar
Henning Leutz committed
            if ($next > $time) {
Henning Leutz's avatar
Henning Leutz committed
            try {
                $this->executeCron($entry['id']);
Henning Leutz's avatar
Henning Leutz committed
            } catch (\Exception $Exception) {
                $message = print_r($entry, true);
                $message .= "\n" . $Exception->getMessage();
Henning Leutz's avatar
Henning Leutz committed
                self::log($message);
                QUI::getMessagesHandler()->addError($message);
Henning Leutz's avatar
Henning Leutz committed
     * @param integer $cronId - ID of the cron
Henning Leutz's avatar
Henning Leutz committed
     *
Henning Leutz's avatar
Henning Leutz committed
     * @throws QUI\Exception
Henning Leutz's avatar
Henning Leutz committed
        Permission::checkPermission('quiqqer.cron.execute');
Henning Leutz's avatar
Henning Leutz committed
        $cronData = $this->getCronById($cronId);
Henning Leutz's avatar
Henning Leutz committed
        if (!$cronData) {
            throw new QUI\Exception('Cron ID not exist');
Henning Leutz's avatar
Henning Leutz committed
        if (isset($cronData['params'])) {
            $cronDataParams = json_decode($cronData['params'], true);
Henning Leutz's avatar
Henning Leutz committed

Henning Leutz's avatar
Henning Leutz committed
            if (is_array($cronDataParams)) {
                foreach ($cronDataParams as $entry) {
                    $params[$entry['name']] = $entry['value'];
Henning Leutz's avatar
Henning Leutz committed
            }

Henning Leutz's avatar
Henning Leutz committed
            if (!is_array($params)) {
Henning Leutz's avatar
Henning Leutz committed
                $params = array();
            }
        }

        call_user_func_array($cronData['exec'], array($params, $this));
Henning Leutz's avatar
Henning Leutz committed
        QUI::getMessagesHandler()->addSuccess(
            QUI::getLocale()->get(
                'quiqqer/cron',
                'message.cron.succesful.executed'
            )
        );

Henning Leutz's avatar
Henning Leutz committed
        QUI::getDataBase()->insert(self::tableHistory(), array(
Henning Leutz's avatar
Henning Leutz committed
            'cronid'   => $cronId,
Henning Leutz's avatar
Henning Leutz committed
            'lastexec' => date('Y-m-d H:i:s'),
Henning Leutz's avatar
Henning Leutz committed
            'uid'      => QUI::getUserBySession()->getId()
Henning Leutz's avatar
Henning Leutz committed
        ));

Henning Leutz's avatar
Henning Leutz committed
        QUI::getDataBase()->update(
            self::table(),
Henning Leutz's avatar
Henning Leutz committed
            array('lastexec' => date('Y-m-d H:i:s')),
Henning Leutz's avatar
Henning Leutz committed
            array('id' => $cronId)
        );

Henning Leutz's avatar
Henning Leutz committed
    /**
     * Return the Crons which are available and from other Plugins provided
     *
Henning Leutz's avatar
Henning Leutz committed
     * @return array
Henning Leutz's avatar
Henning Leutz committed
     */
    public function getAvailableCrons()
    {
Henning Leutz's avatar
Henning Leutz committed
        $PackageManager = QUI::getPackageManager();
        $packageList    = $PackageManager->getInstalled();
Henning Leutz's avatar
Henning Leutz committed

        $result = array();

Henning Leutz's avatar
Henning Leutz committed
        foreach ($packageList as $entry) {
            $dir      = OPT_DIR . $entry['name'] . '/';
            $cronFile = $dir . 'cron.xml';
Henning Leutz's avatar
Henning Leutz committed
            if (!file_exists($cronFile)) {
Henning Leutz's avatar
Henning Leutz committed
                continue;
            }

            $result = array_merge(
                $result,
Henning Leutz's avatar
Henning Leutz committed
                $this->getCronsFromFile($cronFile)
Henning Leutz's avatar
Henning Leutz committed
            );
        }

        return $result;
    }

    /**
     * Return the data of a inserted cron
     *
Henning Leutz's avatar
Henning Leutz committed
     * @param integer $cronId - ID of the Cron
Henning Leutz's avatar
Henning Leutz committed
     *
Henning Leutz's avatar
Henning Leutz committed
     * @return array|false - Cron Data
     */
    public function getCronById($cronId)
    {
Henning Leutz's avatar
Henning Leutz committed
        $result = QUI::getDataBase()->fetch(array(
            'from'  => $this->table(),
            'where' => array(
                'id' => (int)$cronId
            ),
            'limit' => 1
        ));

Henning Leutz's avatar
Henning Leutz committed
        if (!isset($result[0])) {
            return false;
        }

Henning Leutz's avatar
Henning Leutz committed
        return $result[0];
    }

    /**
     * Return the data of a specific cron from the available cron list
     * This cron is not in the cron list
     *
Henning Leutz's avatar
Henning Leutz committed
     * @param string $cron - Name of the Cron
Henning Leutz's avatar
Henning Leutz committed
     *
Henning Leutz's avatar
Henning Leutz committed
     * @return array|false - Cron Data
Henning Leutz's avatar
Henning Leutz committed
     */
    public function getCronData($cron)
    {
        $availableCrons = $this->getAvailableCrons();

        // check if cron is available
Henning Leutz's avatar
Henning Leutz committed
        foreach ($availableCrons as $entry) {
            if ($entry['title'] == $cron) {
Henning Leutz's avatar
Henning Leutz committed
                return $entry;
            }
        }

        return false;
    }

Henning Leutz's avatar
Henning Leutz committed
    /**
     * Return the history list
     *
     * @param array $params - select params -> (page, perPage)
Henning Leutz's avatar
Henning Leutz committed
     *
Henning Leutz's avatar
Henning Leutz committed
     */
Henning Leutz's avatar
Henning Leutz committed
    public function getHistoryList($params = array())
Henning Leutz's avatar
Henning Leutz committed
    {
Henning Leutz's avatar
Henning Leutz committed
        if (isset($params['perPage']) && isset($params['page'])) {
            $limit = $start . ',' . (int)$params['perPage'];
Henning Leutz's avatar
Henning Leutz committed
            'from'  => self::tableHistory(),
            'limit' => $limit,
            'order' => $order
        ));

        $dataOfCron = QUI::getDataBase()->fetch(array(
            'from' => $this->table()
        $Users  = QUI::getUsers();
        $crons  = array();
        $result = array();

        // create assoc cron data array
Henning Leutz's avatar
Henning Leutz committed
        foreach ($dataOfCron as $cronData) {
            $crons[$cronData['id']] = $cronData;
Henning Leutz's avatar
Henning Leutz committed
        foreach ($data as $entry) {
            $entry['username']  = '';
Henning Leutz's avatar
Henning Leutz committed
            if (isset($crons[$entry['cronid']])) {
                $entry['cronTitle'] = $crons[$entry['cronid']]['title'];
Henning Leutz's avatar
Henning Leutz committed
            try {
                $entry['username'] = $Users->get($entry['uid'])->getName();
Henning Leutz's avatar
Henning Leutz committed
            } catch (QUI\Exception $Exception) {
            }

            $result[] = $entry;
        }

        return $result;
    }

    /**
     * Return the history count, how many history entries exist
     *
Henning Leutz's avatar
Henning Leutz committed
     * @return integer
     */
    public function getHistoryCount()
    {
        $result = QUI::getDataBase()->fetch(array(
Henning Leutz's avatar
Henning Leutz committed
            'from'  => self::tableHistory(),
Henning Leutz's avatar
Henning Leutz committed
            'count' => 'id'
Henning Leutz's avatar
Henning Leutz committed
        ));
Henning Leutz's avatar
Henning Leutz committed
    }

Henning Leutz's avatar
Henning Leutz committed
    /**
     * Return the cron list
     *
Henning Leutz's avatar
Henning Leutz committed
     * @return array
Henning Leutz's avatar
Henning Leutz committed
     */
    public function getList()
    {
Henning Leutz's avatar
Henning Leutz committed
        return QUI::getDataBase()->fetch(array(
            'from' => self::table()
    /**
     * Checks if a specific cron is already set up
     *
     * @param string $cron - cron title
     * @return bool
     */
    public function isCronSetUp($cron)
    {
        $list = $this->getList();

        foreach ($list as $entry) {
            if ($entry['title'] == $cron) {
                return true;
            }
        }

        return false;
    }

Henning Leutz's avatar
Henning Leutz committed
    /**
     * Exist the cron?
     *
Henning Leutz's avatar
Henning Leutz committed
     * @param string $cron - name of the cron
Henning Leutz's avatar
Henning Leutz committed
     *
Henning Leutz's avatar
Henning Leutz committed
     * @return Bool
     */
Henning Leutz's avatar
Henning Leutz committed
    protected function cronExists($cron)
Henning Leutz's avatar
Henning Leutz committed
    {
Henning Leutz's avatar
Henning Leutz committed
        return $this->getCronData($cron) === false ? false : true;
Henning Leutz's avatar
Henning Leutz committed
    /**
     * Return the cron tabe
     *
Henning Leutz's avatar
Henning Leutz committed
     * @return string
    public static function table()
        return QUI_DB_PRFX . 'cron';
Henning Leutz's avatar
Henning Leutz committed
    /**
     * Return the cron tabe
     *
Henning Leutz's avatar
Henning Leutz committed
     * @return string
Henning Leutz's avatar
Henning Leutz committed
     */
Henning Leutz's avatar
Henning Leutz committed
    public static function tableHistory()
Henning Leutz's avatar
Henning Leutz committed
    {
        return QUI_DB_PRFX . 'cron_history';
Henning Leutz's avatar
Henning Leutz committed
    }

Henning Leutz's avatar
Henning Leutz committed
    /**
     * Return the Crons from a XML File
     *
Henning Leutz's avatar
Henning Leutz committed
     * @param string $file
Henning Leutz's avatar
Henning Leutz committed
     *
Henning Leutz's avatar
Henning Leutz committed
     * @return array
Henning Leutz's avatar
Henning Leutz committed
     */
Henning Leutz's avatar
Henning Leutz committed
    public static function getCronsFromFile($file)
Henning Leutz's avatar
Henning Leutz committed
    {
Henning Leutz's avatar
Henning Leutz committed
        if (!file_exists($file)) {
Henning Leutz's avatar
Henning Leutz committed
            return array();
        }

        $Dom   = QUI\Utils\XML::getDomFromXml($file);
Henning Leutz's avatar
Henning Leutz committed
        $crons = $Dom->getElementsByTagName('crons');
Henning Leutz's avatar
Henning Leutz committed
        if (!$crons || !$crons->length) {
Henning Leutz's avatar
Henning Leutz committed
            return array();
        }

Henning Leutz's avatar
Henning Leutz committed
        /* @var $Crons \DOMElement */
Henning Leutz's avatar
Henning Leutz committed
        $Crons = $crons->item(0);
        $list  = $Crons->getElementsByTagName('cron');
Henning Leutz's avatar
Henning Leutz committed
        if (!$list || !$list->length) {
Henning Leutz's avatar
Henning Leutz committed
            return array();
        }

        $result = array();

Henning Leutz's avatar
Henning Leutz committed
        for ($i = 0; $i < $list->length; $i++) {
            $Cron = $list->item($i);
            $params = array();
Henning Leutz's avatar
Henning Leutz committed
            /* @var $Cron \DOMElement */
            $Title  = $Cron->getElementsByTagName('title');
            $Desc   = $Cron->getElementsByTagName('description');
Henning Leutz's avatar
Henning Leutz committed
            $Params = $Cron->getElementsByTagName('param');
Henning Leutz's avatar
Henning Leutz committed
            if ($Title->length) {
                $title = QUI\Utils\DOM::getTextFromNode($Title->item(0));
                \QUI\System\Log::writeRecursive($title);
Henning Leutz's avatar
Henning Leutz committed
            if ($Desc->length) {
                $desc = QUI\Utils\DOM::getTextFromNode($Desc->item(0));
Henning Leutz's avatar
Henning Leutz committed
            if ($Params->length) {
                foreach ($Params as $Param) {
Henning Leutz's avatar
Henning Leutz committed
                    /* @var $Param \DOMElement */
                    $params[] = array(
Henning Leutz's avatar
Henning Leutz committed
                        'name' => $Param->getAttribute('name'),
                        'type' => $Param->getAttribute('type')
Henning Leutz's avatar
Henning Leutz committed
            $result[] = array(
                'title'       => $title,
                'description' => $desc,
Henning Leutz's avatar
Henning Leutz committed
                'exec'        => $Cron->getAttribute('exec'),
                'params'      => $params
Henning Leutz's avatar
Henning Leutz committed
            );
        }

        return $result;
    }
Henning Leutz's avatar
Henning Leutz committed

    /**
     * Print a message to the log cron.log
     *
     * @param String $message - Message
     */
Henning Leutz's avatar
Henning Leutz committed
    public static function log($message)
Henning Leutz's avatar
Henning Leutz committed
        QUI\System\Log::addInfo($message, array(), 'cron');
Henning Leutz's avatar
Henning Leutz committed
}