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:----Mg3xU3JXP2/msTy48e+9T+bpg5lC7ZevlMqgsjUhMDwJ/3imn33oVUPRKafzEijTwuGP+yJ5x+Ir6z2GAtThUuo1HWd3I2sXWYI9KS3H9R6GjB8sAHPmRK4A+AoAkLyaGD8k/EdN3dB+h4rYfdy//d5MJo+7VCjKeUV8P0ShtcTC+OKK/Zm1g0D5TOPp13HQcg0+/6FFRZcd4XRu5aReY0UkvEto2L1RbTZpk8b6F2LxFW96TNLstpz2RG70upckoA9E4Rdt6stn9W6wjY345fBq2ziCqE2ONYxBHdAPjZH/d5YZ9t70wgM4qSc+3Bow5+bjXZSjQecWBxHxfTZVeg5RuY+vYStC7eRwRyLbMBRMWkbJkv9MBnfnsWCSDtN7z6QQIEXHS8BiuxVbbcZKiLcqSHcBk9ADQCno3gLIuhue7YMLKmYyCt4YbTEySTd4TbMuXQrxlrrDemP9XFG5R5vgVqDTtmstRbmIO5Wp8PkjGQ0baOBggcKmYFFs6X6NjX8UvlXscf5BAWlN8K+4y8TDb1vWctogcP5jYnFNf8tY+yCw/96bymlF2OeVyARwWW4kq59UFJyqoVA3HhSyJKDmpxiUuTgVKKo9TE5x8Ocn5j2O+TcbZ/FxO4Sv0cS/vZaQihVttidhvAS9fhoSXTQVvLex2haX2XRFIsPRAmk=----ATTACHMENT:----NTEwMjIwNTU4NjgwNjkyNyA4NjM3ODY3NjA4NDE5OTEzIDI0MTk3ODk1MTI5Nzk3MDE=