_temp_cron = Factory::getLocations()->getTempDir() . '/' . self::TEMP_FILE; } public static function getPublicCron():string { return sprintf(self::CRON_URL, Wordpress::getSiteURL(), Wordpress::WP_CONTENT, Wordpress::WP_PLUGINS, Factory::getConfig()->getCronToken()); } public static function getCommand():string { $php = Factory::getSettingsGeneral()->getPHPCLILocation(); $php_escaped = Util::escapeshellargCron(trim($php) ?: 'php'); $cron_escaped = Util::escapeshellargCron(self::CRON_FILE); return sprintf("* * * * * %s %s > /dev/null 2>&1 &", $php_escaped, $cron_escaped); } public function getCrontab():array { if($this->_crontab === null && !Execute::run('crontab -l', $output)) $this->_crontab = $output; return $this->_crontab ?? []; } private function _addCron():array { $output = []; foreach($this->getCrontab() as $line) { $line = trim($line); if( !$line || preg_match('/no\s*crontab\s*for/i', $line) || strpos($line, '#') !== false ) continue; $output[] = $line; } $output[] = $this->getCommand(); return $output; } private function _removeCron():array { $output = []; foreach($this->getCrontab() as $line) if (strpos($line, self::CRON_FILE) === false) $output[] = $line; return $output; } public function buildCrontab ($remove = false):string { $output = $remove ? $this->_removeCron() : $this->_addCron(); return implode(PHP_EOL, $output) . PHP_EOL; } private function _createTempCron($remove = false): bool { $crontab = $this->buildCrontab($remove); $old = umask(077); try { $created = file_put_contents($this->_temp_cron, $crontab); } finally { umask($old); // Always restore, even on exception } return $created !== false; } public function crontabExists():bool { foreach($this->getCrontab() as $line) if (strpos($line, self::CRON_FILE) !== false) return true; return false; } public function removeCrontab():void { if( !$this->crontabExists() || // not found in crontab / cannot read - nothing to do !$this->_createTempCron(true) // cannot create tempcron, cannot continue ) return; $temp_escaped = Util::escapeshellarg($this->_temp_cron); if(!Execute::run('crontab ' . $temp_escaped)) { $config = Factory::getSettingsAutomation(); $config->setCronStatusEnabled(0); $config->save(); Alert::add('Crontab Removed', 'System level crontab successfully removed', Alert::LEVEL_INFORMATION); } } public function addCrontab():void { if( $this->crontabExists() || !$this->_createTempCron() ) return; $temp_escaped = Util::escapeshellarg($this->_temp_cron); if (!Execute::run('crontab ' . $temp_escaped)) { $config = Factory::getSettingsAutomation(); $config->setCronStatusEnabled(1); $config->save(); Alert::add('Crontab Added', 'System level crontab successfully added', Alert::LEVEL_INFORMATION); } } }