1+ <?php
2+ class Core_Cron{
3+
4+ public static function update_interval ($ code )
5+ {
6+ $ bind = array (
7+ 'record_code ' => $ code ,
8+ 'now ' => Phpr_DateTime::now ()->toSqlDateTime ()
9+ );
10+ Db_DbHelper::query ('insert into core_cron_table (record_code, updated_at) values (:record_code, now()) on duplicate key update updated_at =:now ' , $ bind );
11+ }
12+
13+ public static function get_interval ($ code )
14+ {
15+ $ interval = Db_DbHelper::scalar ('select updated_at from core_cron_table where record_code =:record_code ' , array ('record_code ' =>$ code ));
16+ if (!$ interval )
17+ {
18+ self ::update_interval ($ code );
19+ $ interval = Phpr_DateTime::now ()->toSqlDateTime ();
20+ }
21+
22+ return $ interval ;
23+ }
24+
25+ public static function execute_cron ()
26+ {
27+ try
28+ {
29+ // Jobs are one off executions
30+ self ::execute_cronjobs ();
31+
32+ // Tables are regular executions
33+ self ::execute_crontabs ();
34+ }
35+ catch (Exception $ ex )
36+ {
37+ echo $ ex ->getMessage ();
38+ Phpr::$ events ->fire_event ('core:on_execute_cron_exception ' ,$ ex );
39+ }
40+ }
41+
42+ // Usage:
43+ // Core_Cron::queue_job('User_Model::static_method', array('param1', 'param2', 'param3'));
44+ // Executes:
45+ // User_Model::static_method('param1', 'param2', 'param3');
46+ public static function queue_job ($ handler_name , $ param_data =array ())
47+ {
48+ $ bind = array (
49+ 'handler_name ' => $ handler_name ,
50+ 'param_data ' => serialize ($ param_data ),
51+ 'now ' => Phpr_DateTime::now ()->toSqlDateTime ()
52+ );
53+ Db_DbHelper::query ('insert into core_cron_jobs (handler_name, param_data, created_at) values (:handler_name, :param_data, now()) ' , $ bind );
54+ }
55+
56+ private static function execute_cronjobs ()
57+ {
58+ // Worker can perform only 5 jobs per run
59+ //
60+ $ jobs = Db_DbHelper::objectArray ('select * from core_cron_jobs order by created_at asc limit 5 ' );
61+
62+ foreach ($ jobs as $ job )
63+ {
64+ Db_DbHelper::query ('delete from core_cron_jobs where id=:id limit 1 ' , array ('id ' =>$ job ->id ));
65+
66+ $ params = $ job ->param_data ? unserialize ($ job ->param_data ) : array ();
67+ $ parts = explode (':: ' , $ job ->handler_name );
68+ if (count ($ parts ) < 1 )
69+ continue ;
70+
71+ $ model_class = $ parts [0 ];
72+ if (!isset ($ parts [1 ]))
73+ return ;
74+
75+ $ method_name = $ parts [1 ];
76+
77+ if (method_exists ($ model_class , $ method_name ))
78+ call_user_func_array (array ($ model_class , $ method_name ), $ params );
79+ }
80+ }
81+
82+ private static function execute_crontabs ()
83+ {
84+ $ modules = Core_ModuleManager::listModules ();
85+ foreach ($ modules as $ module )
86+ {
87+ if (!method_exists ($ module , 'subscribe_crontab ' ))
88+ continue ;
89+
90+ $ module_id = $ module ->getId ();
91+ $ cron_items = $ module ->subscribe_crontab ();
92+
93+ if (!is_array ($ cron_items ))
94+ continue ;
95+
96+ foreach ($ cron_items as $ code =>$ options )
97+ {
98+ $ code = $ module_id . '_ ' . $ code ;
99+ if (!isset ($ options ['interval ' ]) || !isset ($ options ['method ' ]))
100+ continue ;
101+
102+ $ last_exec = Phpr_DateTime::parse (self ::get_interval ($ code ), Phpr_DateTime::universalDateTimeFormat);
103+ $ next_exec = $ last_exec ->addMinutes ($ options ['interval ' ]);
104+ $ can_execute = Phpr_DateTime::now ()->compare ($ next_exec );
105+
106+ if ($ can_execute == -1 )
107+ continue ;
108+
109+ try
110+ {
111+ $ method = $ options ['method ' ];
112+ if ($ module ->$ method ())
113+ self ::update_interval ( $ code );
114+
115+ }
116+ catch (Exception $ ex )
117+ {
118+ echo "Error in cron: " . $ code . PHP_EOL ;
119+ echo $ ex ->getMessage ();
120+ }
121+ }
122+ }
123+ }
124+ }
0 commit comments