1: <?php
2:
3: // load config
4: if(!isset($config)) {
5: require_once 'AlphaConfig.inc';
6: $config = AlphaConfig::getInstance();
7:
8: require_once $config->get('app.root').'alpha/util/AlphaAutoLoader.inc';
9: }
10:
11: /**
12: *
13: * The main class responsible for running custom cron tasks found under the [webapp]/tasks
14: * directory. This class should be executed from Linux cron via the CLI.
15: *
16: * @package alpha::util
17: * @since 1.0
18: * @author John Collins <dev@alphaframework.org>
19: * @version $Id: AlphaCronManager.inc 1548 2012-07-29 17:07:07Z alphadevx $
20: * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
21: * @copyright Copyright (c) 2012, John Collins (founder of Alpha Framework).
22: * All rights reserved.
23: *
24: * <pre>
25: * Redistribution and use in source and binary forms, with or
26: * without modification, are permitted provided that the
27: * following conditions are met:
28: *
29: * * Redistributions of source code must retain the above
30: * copyright notice, this list of conditions and the
31: * following disclaimer.
32: * * Redistributions in binary form must reproduce the above
33: * copyright notice, this list of conditions and the
34: * following disclaimer in the documentation and/or other
35: * materials provided with the distribution.
36: * * Neither the name of the Alpha Framework nor the names
37: * of its contributors may be used to endorse or promote
38: * products derived from this software without specific
39: * prior written permission.
40: *
41: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
42: * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
43: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
44: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45: * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
46: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
48: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
51: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
52: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
53: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54: * </pre>
55: *
56: */
57: class AlphaCronManager {
58: /**
59: * Trace logger
60: *
61: * @var Logger
62: * @since 1.0
63: */
64: private static $logger = null;
65:
66: /**
67: * Constructor
68: *
69: * @since 1.0
70: */
71: public function __construct() {
72: global $config;
73:
74: self::$logger = new Logger('AlphaCronManager');
75: self::$logger->setLogFile($config->get('app.root').'logs/tasks.log');
76:
77: self::$logger->debug('>>__construct()');
78:
79: self::$logger->info('New AlphaCronManager invoked');
80:
81: $taskList = self::getTaskClassNames();
82:
83: self::$logger->info('Found ['.count($taskList).'] tasks in the directory ['.$config->get('app.root').'tasks]');
84:
85: foreach($taskList as $taskClass) {
86: self::$logger->info('Loading task ['.$taskClass.']');
87: self::loadClassDef($taskClass);
88: $task = new $taskClass;
89:
90: $startTime = microtime(true);
91: $maxAllowedTime = $startTime+$task->getMaxRunTime();
92:
93: self::$logger->info('Start time is ['.$startTime.'], maximum task run time is ['.$task->getMaxRunTime().']');
94:
95: // only continue to execute for the task max time
96: set_time_limit($task->getMaxRunTime());
97: $task->doTask();
98:
99: self::$logger->info('Done in ['.round(microtime(true)-$startTime, 5).'] seconds');
100: }
101:
102: self::$logger->info('Finished processing all cron tasks');
103:
104: self::$logger->debug('<<__construct');
105: }
106:
107: /**
108: * Loops over the /tasks directory and builds an array of all of the task
109: * class names in the system.
110: *
111: * @return array
112: * @since 1.0
113: */
114: public static function getTaskClassNames() {
115: global $config;
116:
117: if(self::$logger == null) {
118: self::$logger = new Logger('AlphaCronManager');
119: self::$logger->setLogFile($config->get('app.root').'logs/tasks.log');
120: }
121: self::$logger->debug('>>getTaskClassNames()');
122:
123: global $config;
124:
125: $classNameArray = array();
126:
127: $handle = opendir($config->get('app.root').'tasks');
128:
129: // loop over the custom task directory
130: while (false !== ($file = readdir($handle))) {
131: if (preg_match("/Task.inc/", $file)) {
132: $classname = substr($file, 0, -4);
133:
134: array_push($classNameArray, $classname);
135: }
136: }
137:
138: $handle = opendir($config->get('app.root').'alpha/tasks');
139:
140: // loop over the custom task directory
141: while (false !== ($file = readdir($handle))) {
142: if (preg_match("/Task.inc/", $file)) {
143: $classname = substr($file, 0, -4);
144:
145: array_push($classNameArray, $classname);
146: }
147: }
148:
149: self::$logger->debug('<<getTaskClassNames ['.var_export($classNameArray, true).']');
150: return $classNameArray;
151: }
152:
153: /**
154: * Loads the definition for the task classname provided
155: *
156: * @param string $classname
157: * @since 1.0
158: */
159: public static function loadClassDef($classname) {
160: global $config;
161:
162: if(self::$logger == null) {
163: self::$logger = new Logger('AlphaCronManager');
164: self::$logger->setLogFile($config->get('app.root').'logs/tasks.log');
165: }
166: self::$logger->debug('>>loadClassDef(classname=['.$classname.'])');
167:
168: if(file_exists($config->get('app.root').'tasks/'.$classname.'.inc'))
169: require_once $config->get('app.root').'tasks/'.$classname.'.inc';
170: elseif(file_exists($config->get('app.root').'alpha/tasks/'.$classname.'.inc'))
171: require_once $config->get('app.root').'alpha/tasks/'.$classname.'.inc';
172: else
173: throw new IllegalArguementException('The class ['.$classname.'] is not defined anywhere!');
174:
175: self::$logger->debug('<<loadClassDef');
176: }
177: }
178:
179: // invoke a cron manager object
180: $processor = new AlphaCronManager();
181:
182: ?>