]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/SchedulersJobs/SchedulersJob.php
Release 6.1.5
[Github/sugarcrm.git] / modules / SchedulersJobs / SchedulersJob.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38
39
40
41 class SchedulersJob extends SugarBean {
42         // schema attributes
43         var $id = '';
44         var $deleted = '';
45         var $date_entered = '';
46         var $date_modified = '';
47         var $scheduler_id = '';
48         var $execute_time = '';
49         var $status;
50         // standard SugarBean child attrs
51         var $table_name         = "schedulers_times";
52         var $object_name                = "SchedulersJob";
53         var $module_dir         = "SchedulersJobs";
54         var $new_schema         = true;
55         var $process_save_dates = true;
56         // related fields
57         var $job_name;  // the Scheduler's 'name' field
58         var $job;               // the Scheduler's 'job' field
59         // object specific attributes
60         var $user; // User object
61         var $scheduler; // Scheduler parent
62         
63         /**
64          * Sole constructor.
65          */
66         function SchedulersJob($init=true) {
67                 parent::SugarBean();
68                 
69                 if($init) {
70                         
71                         $user = new User();
72                         $user->retrieve('1'); // Scheduler jobs run as Admin
73                         $this->user = $user;
74                 }
75
76         }
77         
78         ///////////////////////////////////////////////////////////////////////////
79         ////    SCHEDULERSJOB HELPER FUNCTIONS
80
81         function fireSelf($id) {
82                 
83                 $sched = new Scheduler();
84                 $sched->retrieve($id);
85                 
86                 $exJob = explode('::', $sched->job);
87
88                 if(is_array($exJob)) {
89                         $this->scheduler_id     = $sched->id;
90                         $this->scheduler                = $sched;
91                         $this->execute_time     = $this->handleDateFormat('now');
92                         $this->save();
93                         
94                         if($exJob[0] == 'function') {
95                                 $GLOBALS['log']->debug('----->Scheduler found a job of type FUNCTION');
96                                 require_once('modules/Schedulers/_AddJobsHere.php');
97
98                                 $this->setJobFlag(1);
99                                 
100                                 $func = $exJob[1];
101                                 $GLOBALS['log']->debug('----->SchedulersJob firing '.$func);
102                                 
103                                 $res = call_user_func($func);
104                                 if($res) {
105                                         $this->setJobFlag(2);
106                                         $this->finishJob();
107                                         return true;
108                                 } else {
109                                         $this->setJobFlag(3);
110                                         return false;
111                                 }
112                         } elseif($exJob[0] == 'url') {
113                                 if(function_exists('curl_init')) {
114                                         $GLOBALS['log']->debug('----->SchedulersJob found a job of type URL');
115                                         $this->setJobFlag(1);
116         
117                                         $GLOBALS['log']->debug('----->SchedulersJob firing URL job: '.$exJob[1]);
118                                         if($this->fireUrl($exJob[1])) {
119                                                 $this->setJobFlag(2);
120                                                 $this->finishJob();
121                                                 return true;
122                                         } else {
123                                                 $this->setJobFlag(3);
124                                                 return false;
125                                         }
126                                 } else {
127                                         $this->setJobFlag(4);
128                                         return false;
129                                 }
130                         }
131                 }
132                 return false;
133         }
134
135         /**
136          * handles some date/time foramtting
137          * @param string time Time (usually "now")
138          * @param object user User, usually admin (id = '1')
139          * @param boolean to_local, convert to user's time format
140          * @return string formatted time.
141          */
142         function handleDateFormat($time, $user=null, $to_local=true) {
143                 global $timedate;
144                 
145                 if(!isset($timedate) || empty($timedate)) {
146                         $timedate = new TimeDate();
147                 }
148                 
149                 // get proper user
150                 $user = (empty($user)) ? $this->user : $user;
151                 $dbTime = gmdate($GLOBALS['timedate']->get_db_date_time_format(), strtotime($time));
152
153                 if ($to_local) {
154                     $ret = $timedate->to_display_date_time($dbTime, true, true, $user);
155                     return $ret;
156                 }
157                 
158                 return $dbTime;
159         }
160         
161         function setJobFlag($flag) {
162                 $trackerManager = TrackerManager::getInstance();
163                 $trackerManager->pause();               
164                 $status = array (0 => 'ready', 1 => 'in progress', 2 => 'completed', 3 => 'failed', 4 => 'no curl');
165                 $statusScheduler = array (0 => 'Active', 1 => 'In Progress', 2 => 'Active', 3 => 'Active', 4 => 'Active');
166                 $GLOBALS['log']->info('-----> SchedulersJob setting Job flag: '.$status[$flag].' AND setting Scheduler status to: '.$statusScheduler[$flag]);
167                 
168                 $time = $this->handleDateFormat('now');
169                 $this->status = $status[$flag];
170                 $this->scheduler->retrieve($this->scheduler_id);
171                 $this->scheduler->status = $statusScheduler[$flag];
172                 $this->scheduler->save();
173                 $this->save();
174                 $this->retrieve($this->id);
175                 $trackerManager->unPause();
176         }
177         
178         /**
179          * This function takes a job_id, and updates schedulers last_run as well as
180          * soft delete the job instance from schedulers_times
181          * @return      boolean         Success
182          */
183         function finishJob() {
184                 $trackerManager = TrackerManager::getInstance();
185                 $trackerManager->pause();               
186                 $GLOBALS['log']->debug('----->SchedulersJob updating Job Status and finishing Job execution.');
187                 $this->scheduler->retrieve($this->scheduler->id);
188                 $this->scheduler->last_run = gmdate($GLOBALS['timedate']->get_db_date_time_format());
189                 if($this->scheduler->last_run == gmdate($GLOBALS['timedate']->get_db_date_time_format(), strtotime('Jan 01 2000 00:00:00'))) {
190                         $this->scheduler->last_run = $this->handleDateFormat('now');
191                         $GLOBALS['log']->fatal('Scheduler applying bogus date for "Last Run": '.$this->scheduler->last_run);
192                 }
193                 $this->scheduler->save();
194                 $trackerManager->unPause();
195         }
196
197         /** 
198          * This function takes a passed URL and cURLs it to fake multi-threading with another httpd instance
199          * @param       $job            String in URI-clean format
200          * @param       $timeout        Int value in secs for cURL to timeout. 30 default.
201          */
202         //TODO: figure out what error is thrown when no more apache instances can be spun off
203         function fireUrl($job, $timeout=30) {
204                 // cURL inits
205                 $ch = curl_init();
206                 curl_setopt($ch, CURLOPT_URL, $job); // set url 
207                 curl_setopt($ch, CURLOPT_FAILONERROR, true); // silent failure (code >300);
208                 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // do not follow location(); inits - we always use the current
209                 curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
210                 curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false);  // not thread-safe
211                 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // return into a variable to continue program execution
212                 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); // never times out - bad idea?
213                 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); // 5 secs for connect timeout
214                 curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);  // open brand new conn
215                 curl_setopt($ch, CURLOPT_HEADER, true); // do not return header info with result
216                 curl_setopt($ch, CURLOPT_NOPROGRESS, true); // do not have progress bar
217                 curl_setopt($ch, CURLOPT_PORT, $_SERVER['SERVER_PORT']); // set port as reported by Server
218                 //TODO make the below configurable
219                 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // most customers will not have Certificate Authority account
220                 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // most customers will not have Certificate Authority account
221                 
222                 if(constant('PHP_VERSION') > '5.0.0') {
223                         curl_setopt($ch, CURLOPT_NOSIGNAL, true); // ignore any cURL signals to PHP (for multi-threading)
224                 }
225                 $result = curl_exec($ch);
226                 $cInfo = curl_getinfo($ch);     //url,content_type,header_size,request_size,filetime,http_code
227                                                                         //ssl_verify_result,total_time,namelookup_time,connect_time
228                                                                         //pretransfer_time,size_upload,size_download,speed_download,
229                                                                         //speed_upload,download_content_length,upload_content_length
230                                                                         //starttransfer_time,redirect_time
231                 curl_close($ch);
232
233                 if($cInfo['http_code'] < 400) {
234                         $GLOBALS['log']->debug('----->Firing was successful: ('.$job.') at '.$this->handleDateFormat('now'));
235                         $GLOBALS['log']->debug('----->WTIH RESULT: '.strip_tags($result).' AND '.strip_tags(print_r($cInfo)));
236                         return true;
237                 } else {
238                         $GLOBALS['log']->fatal('Job errored: ('.$job.') at '.$this->handleDateFormat('now'));
239                         return false;
240                 }
241         }
242         ////    END SCHEDULERSJOB HELPER FUNCTIONS
243         ///////////////////////////////////////////////////////////////////////////
244
245
246         ///////////////////////////////////////////////////////////////////////////
247         ////    STANDARD SUGARBEAN OVERRIDES
248         /**
249          * This function gets DB data and preps it for ListViews
250          */
251         function get_list_view_data(){
252                 global $mod_strings;
253
254                 $temp_array = $this->get_list_view_array();
255                 $temp_array['JOB_NAME'] = $this->job_name;
256                 $temp_array['JOB']              = $this->job;
257
258         return $temp_array;
259         }
260
261         /** method stub for future customization
262          * 
263          */
264         function fill_in_additional_list_fields() {
265                 $this->fill_in_additional_detail_fields();
266         }
267
268         function fill_in_additional_detail_fields() {
269                 // get the Job Name and Job fields from schedulers table
270 //              $q = "SELECT name, job FROM schedulers WHERE id = '".$this->job_id."'";
271 //              $result = $this->db->query($q);
272 //              $row = $this->db->fetchByAssoc($result);
273 //              $this->job_name = $row['name'];
274 //              $this->job = $row['job'];
275 //              $GLOBALS['log']->info('Assigned Name('.$this->job_name.') and Job('.$this->job.') to Job');
276 //              
277 //              $this->created_by_name = get_assigned_user_name($this->created_by);
278 //              $this->modified_by_name = get_assigned_user_name($this->modified_user_id);
279                 
280     }
281
282         /**
283          * returns the bean name - overrides SugarBean's
284          */
285         function get_summary_text() {
286         if(isset($this->name))
287                 return $this->name;
288         }
289
290         /**
291          * function overrides the one in SugarBean.php
292          */
293
294 }  // end class Job 
295 ?>