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