Skip to content
Code-Schnipsel Gruppen Projekte
Manager.php 12,6 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\Rights\Permission;
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 Array $params - Cron Parameter
Henning Leutz's avatar
Henning Leutz committed
     * @throws QUI\Exception
Henning Leutz's avatar
Henning Leutz committed
     */
Henning Leutz's avatar
Henning Leutz committed
    public function add($cron, $min, $hour, $day, $month, $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 ) )
        {
            throw new QUI\Exception(
                QUI::getLocale()->get( 'quiqqer/cron', 'exception.cron.1001' ),
                1001
            );
Henning Leutz's avatar
Henning Leutz committed
        }

        $cronData = $this->getCronData( $cron );

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

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

Henning Leutz's avatar
Henning Leutz committed
        QUI::getMessagesHandler()->addSuccess(
Henning Leutz's avatar
Henning Leutz committed
            QUI::getLocale()->get( 'quiqqer/cron', 'message.cron.succesful.added' )
Henning Leutz's avatar
Henning Leutz committed
    /**
     * Edit the cron
     *
     * @param String $cron - Name of the Cron
     * @param Integer $cronId
     * @param String $min
     * @param String $hour
     * @param String $day
     * @param String $month
     * @param Array $params
Henning Leutz's avatar
Henning Leutz committed
     * @throws QUI\Exception
    public function edit($cronId, $cron, $min, $hour, $day, $month, $params=array())
Henning Leutz's avatar
Henning Leutz committed
        Permission::checkPermission( 'quiqqer.cron.edit' );
Henning Leutz's avatar
Henning Leutz committed
        if ( !$this->_cronExists( $cron ) )
        {
            throw new QUI\Exception(
                QUI::getLocale()->get( 'quiqqer/cron', 'exception.cron.1002' ),
                1002
            );
        }

        $cronData = $this->getCronData( $cron );

Henning Leutz's avatar
Henning Leutz committed
        QUI::getDataBase()->update($this->Table(), array(
            'exec'   => $cronData['exec'],
            'title'  => $cronData['title'],
Henning Leutz's avatar
Henning Leutz committed
            'min'    => $min,
            'hour'   => $hour,
            'day'    => $day,
            'month'  => $month,
            'params' => json_encode( $params )
        ), array(
            'id' => $cronId
        ));

Henning Leutz's avatar
Henning Leutz committed
        QUI::getMessagesHandler()->addSuccess(
Henning Leutz's avatar
Henning Leutz committed
            'Cron erfolgreich editiert'
        );
    }

    /**
     * activate a cron in the cron list
     * @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
     * @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)
        );
    }

    /**
     * Delete the crons
     * @param Array $ids - Array of the Cron-Ids
     */
    public function deleteCronIds($ids)
    {
Henning Leutz's avatar
Henning Leutz committed
        Permission::checkPermission( 'quiqqer.cron.delete' );
Henning Leutz's avatar
Henning Leutz committed
        $DataBase = QUI::getDataBase();

        foreach ( $ids as $id )
        {
            $id = (int)$id;

            if ( $this->getCronById( $id ) === false ) {
                return;
            }

            $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' );
        $list = $this->getList();
        $time = time();

        foreach ( $list as $entry )
        {
            if ( $entry['active'] != 1 ) {
                continue;
            }

            $lastexec = $entry['lastexec'];

            $min   = $entry['min'];
            $hour  = $entry['hour'];
            $day   = $entry['day'];
            $month = $entry['month'];
            $year  = '*';

Henning Leutz's avatar
Henning Leutz committed
            $Cron = CronExpression::factory(
                "$min $hour $day $month $year"
            );

            $next = $Cron->getNextRunDate( $lastexec )->getTimestamp();

            // no execute
            if ( $next > $time ) {
                continue;
            }

            // execute cron
            $this->executeCron( $entry['id'] );
        }
    }

    /**
     * Execute a cron
     *
     * @param Integer $cronId - ID of the cron
     * @return \QUI\Cron\Manager
Henning Leutz's avatar
Henning Leutz committed
     * @throws QUI\Exception
Henning Leutz's avatar
Henning Leutz committed
        Permission::checkPermission( 'quiqqer.cron.execute' );
        $cronData = $this->getCronById( $cronId );
Henning Leutz's avatar
Henning Leutz committed
        $params   = array();
Henning Leutz's avatar
Henning Leutz committed
            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 );

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

            if ( !is_array( $params ) ) {
                $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,
            '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(
Henning Leutz's avatar
Henning Leutz committed
            self::Table(),
            array('lastexec' => date( 'Y-m-d H:i:s' )),
            array('id' => $cronId)
        );

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

        $result = array();

        foreach ( $packageList as $entry )
        {
            $dir      = OPT_DIR . $entry['name'] .'/';
            $cronFile = $dir . 'cron.xml';

            if ( !file_exists( $cronFile ) ) {
                continue;
            }

            $result = array_merge(
                $result,
                $this->getCronsFromFile( $cronFile )
            );
        }

        return $result;
    }

    /**
     * Return the data of a inserted cron
     *
     * @param Integer $cronId - ID of the Cron
     * @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
        ));

        if ( !isset( $result[ 0 ] ) ) {
            return false;
        }

        return $result[ 0 ];
    }

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

        // check if cron is available
        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)
     * @return array
Henning Leutz's avatar
Henning Leutz committed
     */
    public function getHistoryList($params=array())
Henning Leutz's avatar
Henning Leutz committed
    {
        $limit = '0,20';
        $order = 'lastexec DESC';

        if ( isset( $params['perPage'] ) && isset( $params['page'] ) )
        {
            $start = (int)$params['page'] - 1;
            $limit = $start .','. (int)$params['perPage'];
        }

        $data = QUI::getDataBase()->fetch(array(
            '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
        foreach ( $dataOfCron as $cronData ) {
            $crons[ $cronData['id'] ] = $cronData;
        }


        foreach ( $data as $entry )
        {
            $entry['cronTitle'] = '';
            $entry['username']  = '';

            if ( isset( $crons[ $entry['cronid'] ] ) ) {
                $entry['cronTitle'] = $crons[ $entry['cronid'] ]['title'];
            }

            try
            {
                $entry['username']  = $Users->get( $entry['uid'] )->getName();

            } catch ( QUI\Exception $Exception )
            {

            }

            $result[] = $entry;
        }

        return $result;
    }

    /**
     * Return the history count, how many history entries exist
     *
     * @return Integer
     */
    public function getHistoryCount()
    {
        $result = QUI::getDataBase()->fetch(array(
            'from'   => self::TableHistory(),
            '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
     *
     * @return Array
     */
    public function getList()
    {
Henning Leutz's avatar
Henning Leutz committed
        return QUI::getDataBase()->fetch(array(
Henning Leutz's avatar
Henning Leutz committed
            'from' => self::Table()
        ));
    }

    /**
     * Exist the cron?
     *
Henning Leutz's avatar
Henning Leutz committed
     * @param string $cron - name of the cron
Henning Leutz's avatar
Henning Leutz committed
     * @return Bool
     */
    protected function _cronExists($cron)
    {
        return $this->getCronData( $cron ) === false ? false : true;
    }

    /**
     * static
     */

Henning Leutz's avatar
Henning Leutz committed
    /**
     * Return the cron tabe
     *
     * @return String
     */
    static function Table()
    {
        return QUI_DB_PRFX .'cron';
    }

Henning Leutz's avatar
Henning Leutz committed
    /**
     * Return the cron tabe
     *
     * @return String
     */
    static function TableHistory()
    {
        return QUI_DB_PRFX .'cron_history';
    }

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

Henning Leutz's avatar
Henning Leutz committed
        $Dom   = QUI\Utils\XML::getDomFromXml( $file );
Henning Leutz's avatar
Henning Leutz committed
        $crons = $Dom->getElementsByTagName( 'crons' );

        if ( !$crons || !$crons->length ) {
            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' );

        if ( !$list || !$list->length ) {
            return array();
        }

        $result = array();

        for ( $i = 0; $i < $list->length; $i++ )
        {
            $Cron = $list->item( $i );

            $title = '';
            $desc  = '';

Henning Leutz's avatar
Henning Leutz committed
            /* @var $Cron \DOMElement */
Henning Leutz's avatar
Henning Leutz committed
            $Title = $Cron->getElementsByTagName( 'title' );
            $Desc  = $Cron->getElementsByTagName( 'description' );

            if ( $Title->length ) {
                $title = trim( $Title->item( 0 )->nodeValue );
            }

            if ( $Desc->length ) {
                $desc = trim( $Desc->item( 0 )->nodeValue );
            }

            $result[] = array(
                'title'       => $title,
                'description' => $desc,
                'exec'        => $Cron->getAttribute( 'exec' )
            );
        }

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

    /**
     * Print a message to the log cron.log
     *
     * @param String $message - Message
     */
    static function log($message)
    {
Henning Leutz's avatar
Henning Leutz committed
        $User = QUI::getUsers()->getUserBySession();
        $str  = '['. date('Y-m-d H:i:s') .' :: '. $User->getName() .'] '. $message;
Henning Leutz's avatar
Henning Leutz committed

        QUI\System\Log::write( $str, 'cron' );
    }
Henning Leutz's avatar
Henning Leutz committed
}