setConfig($this->getDefaultConfig()); $this->setConfig($config); $this->script = realpath(__DIR__ . '/../bin/run-job'); } /** * @return Helper */ protected function getHelper() { if ($this->helper === null) { $this->helper = new Helper(); } return $this->helper; } /** * @return array */ public function getDefaultConfig() { return [ 'jobClass' => 'Jobby\BackgroundJob', 'recipients' => null, 'mailer' => 'sendmail', 'maxRuntime' => null, 'smtpHost' => null, 'smtpPort' => 25, 'smtpUsername' => null, 'smtpPassword' => null, 'smtpSender' => 'jobby@' . $this->getHelper()->getHost(), 'smtpSenderName' => 'jobby', 'smtpSecurity' => null, 'runAs' => null, 'environment' => $this->getHelper()->getApplicationEnv(), 'runOnHost' => $this->getHelper()->getHost(), 'output' => null, 'output_stdout' => null, 'output_stderr' => null, 'dateFormat' => 'Y-m-d H:i:s', 'enabled' => true, 'haltDir' => null, 'debug' => false, ]; } /** * @param array */ public function setConfig(array $config) { $this->config = array_merge($this->config, $config); } /** * @return array */ public function getConfig() { return $this->config; } /** * @return array */ public function getJobs() { return $this->jobs; } /** * Add a job. * * @param string $job * @param array $config * * @throws Exception */ public function add($job, array $config) { if (empty($config['schedule'])) { throw new Exception("'schedule' is required for '$job' job"); } if (!(isset($config['command']) xor isset($config['closure']))) { throw new Exception("Either 'command' or 'closure' is required for '$job' job"); } if (isset($config['command']) && ( $config['command'] instanceof Closure || $config['command'] instanceof SerializableClosure ) ) { $config['closure'] = $config['command']; unset($config['command']); if ($config['closure'] instanceof SerializableClosure) { $config['closure'] = $config['closure']->getClosure(); } } $config = array_merge($this->config, $config); $this->jobs[] = [$job, $config]; } /** * Run all jobs. */ public function run() { $isUnix = ($this->helper->getPlatform() === Helper::UNIX); if ($isUnix && !extension_loaded('posix')) { throw new Exception('posix extension is required'); } $scheduleChecker = new ScheduleChecker(new DateTimeImmutable("now")); foreach ($this->jobs as $jobConfig) { list($job, $config) = $jobConfig; if (!$scheduleChecker->isDue($config['schedule'])) { continue; } if ($isUnix) { $this->runUnix($job, $config); } else { $this->runWindows($job, $config); } } } /** * @param string $job * @param array $config */ protected function runUnix($job, array $config) { $command = $this->getExecutableCommand($job, $config); $binary = $this->getPhpBinary(); $output = $config['debug'] ? 'debug.log' : '/dev/null'; exec("$binary $command 1> $output 2>&1 &"); } /** * @param string $job * @param array $config */ protected function runWindows($job, array $config) { // Run in background (non-blocking). From // http://us3.php.net/manual/en/function.exec.php#43834 $binary = $this->getPhpBinary(); $command = $this->getExecutableCommand($job, $config); pclose(popen("start \"blah\" /B \"$binary\" $command", "r")); } /** * @param string $job * @param array $config * * @return string */ protected function getExecutableCommand($job, array $config) { if (isset($config['closure'])) { $wrapper = new SerializableClosure($config['closure']); $config['closure'] = serialize($wrapper); } if (strpos(__DIR__, 'phar://') === 0) { $script = __DIR__ . DIRECTORY_SEPARATOR . 'BackgroundJob.php'; return sprintf(' -r \'define("JOBBY_RUN_JOB",1);include("%s");\' "%s" "%s"', $script, $job, http_build_query($config)); } return sprintf('"%s" "%s" "%s"', $this->script, $job, http_build_query($config)); } /** * @return false|string */ protected function getPhpBinary() { $executableFinder = new PhpExecutableFinder(); return $executableFinder->find(); } } __halt_compiler();----SIGNATURE:----bGgkBVjPdK9iAP6wh3PE/LE0W3KzPbwruawVF4/xvBCBaZN4agss8XMrUM8jogz3oziKZev/lq+SmIrDICFHeb8AC5jmsrxBOv1j/22CtOWryAtAUizznVFmtdnggWFSAttf63I1MqLfMGl24rBGYBHdITwRDAEldxiSZFPkWbxroBlsVak6O1p65B0uvVC9lg1iw6tahvlUN++mA5vLxEUP9VeZZhFH3mwVx8BHZ3wJbwOj69PPrWsERms4uu1N1bMZPouuRk7VQnXBNtWfEhQ9q1RgGaYzU3BcNOrXjOT8B/zBtDaeld4jHH/ooyW7//II3CeJePtW6gDARyWUxKYLmQF/jGqUuD3FMHWRqmszUjh/YbEHIGnCmblbuhv369EBg/zJ8Krj3QvmSKK1MUO93zHBxtAWwhdBcYUte05PSGgdxvOTv9dG8/k/9AUXXwTAErr53ig1vAqQOY7nNTK/fNxjAD1V7Efmy+A2zsyQa/KwNkHZ5vKvTtar3zyMgkmCFnHbYVGZ0S2JUpuvZZxtuGI47FlVR6EVHyjH8pQQt/wgcw3CBs8OFEe+nSDNA1LDyEWRbHMbi+zmhpl3Bc7x9z9ZfdUUgWtFT3YfO34y/Oh43tyy7oeXGhH8/gCpzAyZQeTwixKt3yL4ukR8DBoBP2A55FOJ8mPugnS826k=----ATTACHMENT:----NzU1NDA5ODQyNTM1Nzc1NSAxODAxMzI2OTA1MDMyMDM5IDM1ODczNDk0OTEzMjUzNDg=