Issues (4069)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

modules/SchedulersJobs/SchedulersJob.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3
/*********************************************************************************
4
 * SugarCRM Community Edition is a customer relationship management program developed by
5
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
6
7
 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
8
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
9
 *
10
 * This program is free software; you can redistribute it and/or modify it under
11
 * the terms of the GNU Affero General Public License version 3 as published by the
12
 * Free Software Foundation with the addition of the following permission added
13
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
14
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
15
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
16
 *
17
 * This program is distributed in the hope that it will be useful, but WITHOUT
18
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
20
 * details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License along with
23
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
24
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25
 * 02110-1301 USA.
26
 *
27
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
28
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
29
 *
30
 * The interactive user interfaces in modified source and object code versions
31
 * of this program must display Appropriate Legal Notices, as required under
32
 * Section 5 of the GNU Affero General Public License version 3.
33
 *
34
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
35
 * these Appropriate Legal Notices must retain the display of the "Powered by
36
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
37
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
38
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
39
 ********************************************************************************/
40
41
42
/**
43
 * Job queue job
44
 * @api
45
 */
46
class SchedulersJob extends Basic
47
{
48
    const JOB_STATUS_QUEUED = 'queued';
49
    const JOB_STATUS_RUNNING = 'running';
50
    const JOB_STATUS_DONE = 'done';
51
52
    const JOB_PENDING = 'queued';
53
    const JOB_PARTIAL = 'partial';
54
    const JOB_SUCCESS = 'success';
55
    const JOB_FAILURE = 'failure';
56
57
    // schema attributes
58
	public $id;
59
	public $name;
60
	public $deleted;
61
	public $date_entered;
62
	public $date_modified;
63
	public $scheduler_id;
64
	public $execute_time; // when to execute
65
    public $status;
66
    public $resolution;
67
    public $message;
68
	public $target; // URL or function name
69
    public $data; // Data set
70
    public $requeue; // Requeue on failure?
71
    public $retry_count;
72
    public $failure_count;
73
    public $job_delay=0; // Frequency to run it
74
    public $assigned_user_id; // User under which the task is running
75
    public $client; // Client ID that owns this job
76
    public $execute_time_db;
77
    public $percent_complete; // how much of the job is done
78
79
	// standard SugarBean child attrs
80
	var $table_name		= "job_queue";
81
	var $object_name		= "SchedulersJob";
82
	var $module_dir		= "SchedulersJobs";
83
	var $new_schema		= true;
84
	var $process_save_dates = true;
85
	// related fields
86
	var $job_name;	// the Scheduler's 'name' field
87
	var $job;		// the Scheduler's 'job' field
88
	// object specific attributes
89
	public $user; // User object
90
	var $scheduler; // Scheduler parent
91
	public $min_interval = 30; // minimal interval for job reruns
92
	protected $job_done = true;
93
    protected $old_user;
94
95
	/**
96
	 * Job constructor.
97
	 */
98 35
	function __construct()
99
	{
100 35
        parent::__construct();
101 35
        if(!empty($GLOBALS['sugar_config']['jobs']['min_retry_interval'])) {
102 35
            $this->min_interval = $GLOBALS['sugar_config']['jobs']['min_retry_interval'];
103
        }
104 35
	}
105
106
    /**
107
     * @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead
108
     */
109
    function SchedulersJob(){
110
        $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code';
111
        if(isset($GLOBALS['log'])) {
112
            $GLOBALS['log']->deprecated($deprecatedMessage);
113
        }
114
        else {
115
            trigger_error($deprecatedMessage, E_USER_DEPRECATED);
116
        }
117
        self::__construct();
118
    }
119
120 3
	public function check_date_relationships_load()
121
	{
122
        // Hack to work around the mess with dates being auto-converted to user format on retrieve
123 3
	    $this->execute_time_db = $this->db->fromConvert($this->execute_time, 'datetime');
124 3
	    parent::check_date_relationships_load();
125 3
    }
126
	/**
127
     * handleDateFormat
128
     *
129
	 * This function handles returning a datetime value.  It allows a user instance to be passed in, but will default to the
130
     * user member variable instance if none is found.
131
     *
132
	 * @param string $date String value of the date to calculate, defaults to 'now'
133
	 * @param object $user The User instance to use in calculating the time value, if empty, it will default to user member variable
134
	 * @param boolean $user_format Boolean indicating whether or not to convert to user's time format, defaults to false
135
     *
136
	 * @return string Formatted datetime value
137
	 */
138 1
	function handleDateFormat($date='now', $user=null, $user_format=false) {
139 1
		global $timedate;
140
141 1
		if(!isset($timedate) || empty($timedate))
142
        {
143
			$timedate = new TimeDate();
144
		}
145
146
		// get user for calculation
147 1
		$user = (empty($user)) ? $this->user : $user;
148
149 1
        if($date == 'now')
150
        {
151 1
            $dbTime = $timedate->asUser($timedate->getNow(), $user);
152
        } else {
153 1
            $dbTime = $timedate->asUser($timedate->fromString($date, $user), $user);
0 ignored issues
show
It seems like $timedate->fromString($date, $user) can be null; however, asUser() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
154
        }
155
156
        // if $user_format is set to true then just return as th user's time format, otherwise, return as database format
157 1
        return $user_format ? $dbTime : $timedate->fromUser($dbTime, $user)->asDb();
158
	}
159
160
161
	///////////////////////////////////////////////////////////////////////////
162
	////	SCHEDULERSJOB HELPER FUNCTIONS
163
164
	/**
165
	 * This function takes a passed URL and cURLs it to fake multi-threading with another httpd instance
166
	 * @param	$job		String in URI-clean format
167
	 * @param	$timeout	Int value in secs for cURL to timeout. 30 default.
168
	 */
169 2
	public function fireUrl($job, $timeout=30)
170
	{
171
	// TODO: figure out what error is thrown when no more apache instances can be spun off
172
	    // cURL inits
173 2
		$ch = curl_init();
174 2
		curl_setopt($ch, CURLOPT_URL, $job); // set url
175 2
		curl_setopt($ch, CURLOPT_FAILONERROR, true); // silent failure (code >300);
176 2
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // do not follow location(); inits - we always use the current
177 2
		curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
178 2
		curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false);  // not thread-safe
179 2
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // return into a variable to continue program execution
180 2
		curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); // never times out - bad idea?
181 2
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); // 5 secs for connect timeout
182 2
		curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);  // open brand new conn
183 2
		curl_setopt($ch, CURLOPT_HEADER, true); // do not return header info with result
184 2
		curl_setopt($ch, CURLOPT_NOPROGRESS, true); // do not have progress bar
185 2
		$urlparts = parse_url($job);
186 2
		if(empty($urlparts['port'])) {
187 2
		    if($urlparts['scheme'] == 'https'){
188 2
				$urlparts['port'] = 443;
189
			} else {
190 1
				$urlparts['port'] = 80;
191
			}
192
		}
193 2
		curl_setopt($ch, CURLOPT_PORT, $urlparts['port']); // set port as reported by Server
194
		//TODO make the below configurable
195 2
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // most customers will not have Certificate Authority account
196 2
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // most customers will not have Certificate Authority account
197
198 2
		curl_setopt($ch, CURLOPT_NOSIGNAL, true); // ignore any cURL signals to PHP (for multi-threading)
199 2
		$result = curl_exec($ch);
200 2
		$cInfo = curl_getinfo($ch);	//url,content_type,header_size,request_size,filetime,http_code
201
									//ssl_verify_result,total_time,namelookup_time,connect_time
202
									//pretransfer_time,size_upload,size_download,speed_download,
203
									//speed_upload,download_content_length,upload_content_length
204
									//starttransfer_time,redirect_time
205 2
		if(curl_errno($ch)) {
206 1
		    $this->errors .= curl_errno($ch)."\n";
207
		}
208 2
		curl_close($ch);
209
210 2
		if($result !== FALSE && $cInfo['http_code'] < 400) {
211 2
			$GLOBALS['log']->debug("----->Firing was successful: $job");
212 2
			$GLOBALS['log']->debug('----->WTIH RESULT: '.strip_tags($result).' AND '.strip_tags(print_r($cInfo, true)));
213 2
			return true;
214
		} else {
215 1
			$GLOBALS['log']->fatal("Job failed: $job");
216 1
			return false;
217
		}
218
	}
219
	////	END SCHEDULERSJOB HELPER FUNCTIONS
220
	///////////////////////////////////////////////////////////////////////////
221
222
223
	///////////////////////////////////////////////////////////////////////////
224
	////	STANDARD SUGARBEAN OVERRIDES
225
	/**
226
	 * This function gets DB data and preps it for ListViews
227
	 */
228 1
	function get_list_view_data()
229
	{
230 1
		global $mod_strings;
231
232 1
		$temp_array = $this->get_list_view_array();
233 1
		$temp_array['JOB_NAME'] = $this->job_name;
234 1
		$temp_array['JOB']		= $this->job;
235
236 1
    	return $temp_array;
237
	}
238
239
	/** method stub for future customization
240
	 *
241
	 */
242 1
	function fill_in_additional_list_fields()
243
	{
244 1
		$this->fill_in_additional_detail_fields();
245 1
	}
246
247
248
	/**
249
	 * Mark this job as failed
250
	 * @param string $message
251
	 */
252 1
    public function failJob($message = null)
253
    {
254 1
        return $this->resolveJob(self::JOB_FAILURE, $message);
255
    }
256
257
	/**
258
	 * Mark this job as success
259
	 * @param string $message
260
	 */
261 1
    public function succeedJob($message = null)
262
    {
263 1
        return $this->resolveJob(self::JOB_SUCCESS, $message);
264
    }
265
266
    /**
267
     * Called if job failed but will be retried
268
     */
269
    public function onFailureRetry()
270
    {
271
        // TODO: what we do if job fails, notify somebody?
272
        $this->call_custom_logic("job_failure_retry");
273
    }
274
275
    /**
276
     * Called if job has failed and will not be retried
277
     */
278 4
    public function onFinalFailure()
279
    {
280
        // TODO: what we do if job fails, notify somebody?
281 4
        $this->call_custom_logic("job_failure");
282 4
    }
283
284
    /**
285
     * Resolve job as success or failure
286
     * @param string $resolution One of JOB_ constants that define job status
287
     * @param string $message
288
     * @return bool
289
     */
290 5
    public function resolveJob($resolution, $message = null)
291
    {
292 5
        $GLOBALS['log']->info("Resolving job {$this->id} as $resolution: $message");
293 5
        if($resolution == self::JOB_FAILURE) {
294 4
            $this->failure_count++;
295 4
            if($this->requeue && $this->retry_count > 0) {
296
                // retry failed job
297
                $this->status = self::JOB_STATUS_QUEUED;
298
                if($this->job_delay < $this->min_interval) {
299
                    $this->job_delay = $this->min_interval;
300
                }
301
                $this->execute_time = $GLOBALS['timedate']->getNow()->modify("+{$this->job_delay} seconds")->asDb();
302
                $this->retry_count--;
303
                $GLOBALS['log']->info("Will retry job {$this->id} at {$this->execute_time} ($this->retry_count)");
304
                $this->onFailureRetry();
305
            } else {
306
                // final failure
307 4
                $this->status = self::JOB_STATUS_DONE;
308 4
                $this->onFinalFailure();
309
            }
310
        } else {
311 3
            $this->status = self::JOB_STATUS_DONE;
312
        }
313 5
        $this->addMessages($message);
314 5
        $this->resolution = $resolution;
315 5
        $this->save();
316 5
        if($this->status == self::JOB_STATUS_DONE && $this->resolution == self::JOB_SUCCESS) {
317 3
            $this->updateSchedulerSuccess();
318
        }
319 5
        return true;
320
    }
321
322
    /**
323
     * Update schedulers table on job success
324
     */
325 3
    protected function updateSchedulerSuccess()
326
    {
327 3
        if(empty($this->scheduler_id)) {
328 3
            return;
329
        }
330
        $this->db->query("UPDATE schedulers SET last_run={$this->db->now()} WHERE id=".$this->db->quoted($this->scheduler_id));
331
    }
332
333
    /**
334
     * Assemle job messages
335
     * Takes messages in $this->message, errors & $message and assembles them into $this->message
336
     * @param string $message
337
     */
338 6
    protected function addMessages($message)
339
    {
340 6
        if(!empty($this->errors)) {
341 1
            $this->message .= $this->errors;
342 1
            $this->errors = '';
343
        }
344 6
        if(!empty($message)) {
345 4
            $this->message .= "$message\n";
346
        }
347 6
    }
348
349
    /**
350
     * Rerun this job again
351
     * @param string $message
352
     * @param string $delay how long to delay (default is job's delay)
353
     * @return bool
354
     */
355 1
    public function postponeJob($message = null, $delay = null)
356
    {
357 1
        $this->status = self::JOB_STATUS_QUEUED;
358 1
        $this->addMessages($message);
359 1
        $this->resolution = self::JOB_PARTIAL;
360 1
        if(empty($delay)) {
361
            $delay = intval($this->job_delay);
362
        }
363 1
        $this->execute_time = $GLOBALS['timedate']->getNow()->modify("+$delay seconds")->asDb();
364 1
        $GLOBALS['log']->info("Postponing job {$this->id} to {$this->execute_time}: $message");
365
366 1
        $this->save();
367 1
        return true;
368
    }
369
370
    /**
371
     * Delete a job
372
     * @see SugarBean::mark_deleted($id)
373
     */
374 7
    public function mark_deleted($id)
375
    {
376 7
        return $this->db->query("DELETE FROM {$this->table_name} WHERE id=".$this->db->quoted($id));
377
    }
378
379
    /**
380
     * Shutdown handler to be called if something breaks in the middle of the job
381
     */
382 1
    public function unexpectedExit()
383
    {
384 1
        if(!$this->job_done) {
385
            // Job wasn't properly finished, fail it
386
            $this->resolveJob(self::JOB_FAILURE, translate('ERR_FAILED', 'SchedulersJobs'));
387
        }
388 1
    }
389
390
    /**
391
     * Run the job by ID
392
     * @param string $id
393
     * @param string $client Client that is trying to run the job
394
     * @return bool|string true on success, false on job failure, error message on failure to run
395
     */
396 2
    public static function runJobId($id, $client)
397
    {
398 2
        $job = new self();
399 2
        $job->retrieve($id);
400 2
        if(empty($job->id)) {
401 1
            $GLOBALS['log']->fatal("Job $id not found.");
402 1
            return "Job $id not found.";
403
        }
404 2
        if($job->status != self::JOB_STATUS_RUNNING) {
405 1
            $GLOBALS['log']->fatal("Job $id is not marked as running.");
406 1
            return "Job $id is not marked as running.";
407
        }
408 2
        if($job->client != $client) {
409 1
            $GLOBALS['log']->fatal("Job $id belongs to client {$job->client}, can not run as $client.");
410 1
            return "Job $id belongs to another client, can not run as $client.";
411
        }
412 1
        $job->job_done = false;
413 1
        register_shutdown_function(array($job, "unexpectedExit"));
414 1
        $res = $job->runJob();
415 1
        $job->job_done = true;
416 1
        return $res;
417
    }
418
419
    /**
420
     * Error handler, assembles the error messages
421
     * @param int $errno
422
     * @param string $errstr
423
     * @param string $errfile
424
     * @param int $errline
425
     */
426 2
    public function errorHandler($errno, $errstr, $errfile, $errline)
427
    {
428
        switch($errno)
429
        {
430 2
    		case E_USER_WARNING:
431 2
    		case E_COMPILE_WARNING:
432 2
    		case E_CORE_WARNING:
433 2
    		case E_WARNING:
434 2
    			$type = "Warning";
435 2
    			break;
436 1
    		case E_USER_ERROR:
437 1
    		case E_COMPILE_ERROR:
438 1
    		case E_CORE_ERROR:
439 1
    		case E_ERROR:
440 1
    			$type = "Fatal Error";
441 1
	    		break;
442 1
    		case E_PARSE:
443 1
    			$type = "Parse Error";
444 1
	    		break;
445 1
    		case E_RECOVERABLE_ERROR:
446 1
    			$type = "Recoverable Error";
447 1
	    		break;
448
		    default:
449
		        // Ignore errors we don't know about
450
		        return;
451
    	}
452 2
        $errstr = strip_tags($errstr);
453 2
        $this->errors .= sprintf(translate('ERR_PHP', 'SchedulersJobs'), $type, $errno, $errstr, $errfile, $errline)."\n";
454 2
    }
455
456
    /**
457
     * Change current user to given user
458
     * @param User $user
459
     */
460 1
    protected function sudo($user)
461
    {
462 1
        $GLOBALS['current_user'] = $user;
463
        // Reset the session
464 1
        if(session_id()) {
465
            session_destroy();
466
        }
467 1
        if(!headers_sent()) {
468
    		session_start();
469
            session_regenerate_id();
470
        }
471 1
        $_SESSION['is_valid_session']= true;
472 1
    	$_SESSION['user_id'] = $user->id;
473 1
    	$_SESSION['type'] = 'user';
474 1
    	$_SESSION['authenticated_user_id'] = $user->id;
475 1
    }
476
477
    /**
478
     * Set environment to the user of this job
479
     * @return boolean
480
     */
481 1
    protected function setJobUser()
482
    {
483
        // set up the current user and drop session
484 1
        if(!empty($this->assigned_user_id)) {
485 1
            $this->old_user = $GLOBALS['current_user'];
486 1
            if(empty($this->user->id) || $this->assigned_user_id != $this->user->id) {
487 1
                $this->user = BeanFactory::getBean('Users', $this->assigned_user_id);
488 1
                if(empty($this->user->id)) {
489
                    $this->resolveJob(self::JOB_FAILURE, sprintf(translate('ERR_NOSUCHUSER', 'SchedulersJobs'), $this->assigned_user_id));
490
                    return false;
491
                }
492
            }
493 1
            $this->sudo($this->user);
494
        } else {
495 1
            $this->resolveJob(self::JOB_FAILURE, translate('ERR_NOUSER', 'SchedulersJobs'));
496 1
            return false;
497
        }
498 1
        return true;
499
    }
500
501
    /**
502
     * Restore previous user environment
503
     */
504 1
    protected function restoreJobUser()
505
    {
506 1
        if(!empty($this->old_user->id) && $this->old_user->id != $this->user->id) {
507
            $this->sudo($this->old_user);
508
        }
509 1
    }
510
511
    /**
512
     * Run this job
513
     * @return bool Was the job successful?
514
     */
515 2
    public function runJob()
516
    {
517 2
        require_once('modules/Schedulers/_AddJobsHere.php');
518
519 2
        $this->errors = "";
520 2
        $exJob = explode('::', $this->target, 2);
521 2
        if($exJob[0] == 'function') {
522
            // set up the current user and drop session
523 1
            if(!$this->setJobUser()) {
524 1
                return false;
525
            }
526 1
    		$func = $exJob[1];
527 1
			$GLOBALS['log']->debug("----->SchedulersJob calling function: $func");
528 1
            set_error_handler(array($this, "errorHandler"), E_ALL & ~E_NOTICE & ~E_STRICT);
529 1
			if(!is_callable($func)) {
530
			    $this->resolveJob(self::JOB_FAILURE, sprintf(translate('ERR_CALL', 'SchedulersJobs'), $func));
531
			}
532 1
			$data = array($this);
533 1
			if(!empty($this->data)) {
534
			    $data[] = $this->data;
535
			}
536 1
            $res = call_user_func_array($func, $data);
537 1
            restore_error_handler();
538 1
            $this->restoreJobUser();
539 1
			if($this->status == self::JOB_STATUS_RUNNING) {
540
			    // nobody updated the status yet - job function could do that
541
    			if($res) {
542
    			    $this->resolveJob(self::JOB_SUCCESS);
543
    				return true;
544
    			} else {
545
    			    $this->resolveJob(self::JOB_FAILURE);
546
    			    return false;
547
    			}
548
			} else {
549 1
			    return $this->resolution != self::JOB_FAILURE;
550
			}
551 2
		} elseif($exJob[0] == 'url') {
552 1
			if(function_exists('curl_init')) {
553 1
				$GLOBALS['log']->debug('----->SchedulersJob firing URL job: '.$exJob[1]);
554 1
                set_error_handler(array($this, "errorHandler"), E_ALL & ~E_NOTICE & ~E_STRICT);
555 1
				if($this->fireUrl($exJob[1])) {
556 1
                    restore_error_handler();
557 1
                    $this->resolveJob(self::JOB_SUCCESS);
558 1
					return true;
559
				} else {
560
                    restore_error_handler();
561
				    $this->resolveJob(self::JOB_FAILURE);
562
					return false;
563
				}
564
			} else {
565
			    $this->resolveJob(self::JOB_FAILURE, translate('ERR_CURL', 'SchedulersJobs'));
566
			}
567 1
		} elseif ($exJob[0] == 'class') {
568
            $tmpJob = new $exJob[1]();
569
            if($tmpJob instanceof RunnableSchedulerJob)
570
            {
571
                // set up the current user and drop session
572
                if(!$this->setJobUser()) {
573
                    return false;
574
                }
575
                $tmpJob->setJob($this);
576
                $result = $tmpJob->run($this->data);
577
                $this->restoreJobUser();
578
                if ($this->status == self::JOB_STATUS_RUNNING) {
579
                    // nobody updated the status yet - job class could do that
580
                    if ($result) {
581
                        $this->resolveJob(self::JOB_SUCCESS);
582
                        return true;
583
                    } else {
584
                        $this->resolveJob(self::JOB_FAILURE);
585
                        return false;
586
                    }
587
                } else {
588
                    return $this->resolution != self::JOB_FAILURE;
589
                }
590
            }
591
            else {
592
                $this->resolveJob(self::JOB_FAILURE, sprintf(translate('ERR_JOBTYPE', 'SchedulersJobs'), strip_tags($this->target)));
593
            }
594
        }
595
        else {
596 1
		    $this->resolveJob(self::JOB_FAILURE, sprintf(translate('ERR_JOBTYPE', 'SchedulersJobs'), strip_tags($this->target)));
597
		}
598 1
		return false;
599
    }
600
601
}  // end class Job
602
603
/**
604
 * Runnable job queue job
605
 *
606
 */
607
interface RunnableSchedulerJob
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
608
{
609
    /**
610
     * @abstract
611
     * @param SchedulersJob $job
612
     */
613
    public function setJob(SchedulersJob $job);
614
615
    /**
616
     * @abstract
617
     *
618
     */
619
    public function run($data);
620
}
621