summaryrefslogtreecommitdiff
path: root/plugins/Irc/extlib/phergie/Phergie/Plugin/Cron.php
blob: 1c27f97842edf8736a58a0c8276c5fc7df9777e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?php
/**
 * Phergie
 *
 * PHP version 5
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.
 * It is also available through the world-wide-web at this URL:
 * http://phergie.org/license
 *
 * @category  Phergie
 * @package   Phergie_Plugin_Cron
 * @author    Phergie Development Team <team@phergie.org>
 * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
 * @license   http://phergie.org/license New BSD License
 * @link      http://pear.phergie.org/package/Phergie_Plugin_Cron
 */

/**
 * Allows callbacks to be registered for asynchronous execution.
 *
 * @category Phergie
 * @package  Phergie_Plugin_Cron
 * @author   Phergie Development Team <team@phergie.org>
 * @license  http://phergie.org/license New BSD License
 * @link     http://pear.phergie.org/package/Phergie_Plugin_Cron
 */
class Phergie_Plugin_Cron extends Phergie_Plugin_Abstract
{
    /**
     * Array of all registered callbacks with delays and arguments
     *
     * @var array
     */
    protected $callbacks;

    /**
     * Returns a human-readable representation of a callback for debugging
     * purposes.
     *
     * @param callback $callback Callback to analyze
     *
     * @return string|boolean String representation of the callback or FALSE
     *         if the specified value is not a valid callback
     */
    protected function getCallbackString($callback)
    {
        if (!is_callable($callback)) {
            return false;
        }

        if (is_array($callback)) {
            $class = is_string($callback[0]) ?
                $callback[0] : get_class($callback[0]);
            $method = $class . '::' . $callback[1];
            return $method;
        }

        return $callback;
    }

    /**
     * Registers a callback for execution sometime after a given delay
     * relative to now.
     *
     * @param callback $callback  Callback to be registered
     * @param int      $delay     Delay in seconds from now when the callback
     *        will be executed
     * @param array    $arguments Arguments to pass to the callback when
     *        it's executed
     * @param bool     $repeat    TRUE to automatically re-register the
     *        callback for the same delay after it's executed, FALSE
     *        otherwise
     *
     * @return void
     */
    public function registerCallback($callback, $delay,
        array $arguments = array(), $repeat = false)
    {
        $callbackString = $this->getCallbackString($callback);
        if ($callbackString === false) {
            echo 'DEBUG(Cron): Invalid callback specified - ',
                var_export($callback, true), PHP_EOL;
            return;
        }

        $registered = time();
        $scheduled = $registered + $delay;

        $this->callbacks[] = array(
            'callback'   => $callback,
            'delay'      => $delay,
            'arguments'  => $arguments,
            'registered' => $registered,
            'scheduled'  => $scheduled,
            'repeat'     => $repeat,
        );

        echo 'DEBUG(Cron): Callback ', $callbackString,
            ' scheduled for ', date('H:i:s', $scheduled), PHP_EOL;
    }

    /**
     * Handles callback execution.
     *
     * @return void
     */
    public function onTick()
    {
        $now = time();
        foreach ($this->callbacks as $key => &$callback) {
            $callbackString = $this->getCallbackString($callback);

            $scheduled = $callback['scheduled'];
            if ($time < $scheduled) {
                continue;
            }

            if (empty($callback['arguments'])) {
                call_user_func($callback['callback']);
            } else {
                call_user_func_array(
                    $callback['callback'],
                    $callback['arguments']
                );
            }

            echo 'DEBUG(Cron): Callback ', $callbackString,
                ' scheduled for ', date('H:i:s', $scheduled), ',',
                ' executed at ', date('H:i:s', $now), PHP_EOL;

            if ($callback['repeat']) {
                $callback['scheduled'] = $time + $callback['delay'];
                echo 'DEBUG(Cron): Callback ', $callbackString,
                    ' scheduled for ', date('H:i:s', $callback['scheduled']),
                    PHP_EOL;
            } else {
                echo 'DEBUG(Cron): Callback ', $callbackString,
                    ' removed from callback list', PHP_EOL;
                unset($this->callbacks[$key]);
            }
        }
    }
}