123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Framework\Crontab;
- use Magento\Framework\App\Filesystem\DirectoryList;
- use Magento\Framework\Exception\LocalizedException;
- use Magento\Framework\Filesystem;
- use Magento\Framework\Phrase;
- use Magento\Framework\ShellInterface;
- /**
- * Manager works with cron tasks
- */
- class CrontabManager implements CrontabManagerInterface
- {
- /**
- * @var ShellInterface
- */
- private $shell;
- /**
- * @var Filesystem
- */
- private $filesystem;
- /**
- * @param ShellInterface $shell
- * @param Filesystem $filesystem
- */
- public function __construct(
- ShellInterface $shell,
- Filesystem $filesystem
- ) {
- $this->shell = $shell;
- $this->filesystem = $filesystem;
- }
- /**
- * @return string
- */
- private function getTasksBlockStart()
- {
- $tasksBlockStart = self::TASKS_BLOCK_START;
- if (defined('BP')) {
- $tasksBlockStart .= ' ' . md5(BP);
- }
- return $tasksBlockStart;
- }
- /**
- * @return string
- */
- private function getTasksBlockEnd()
- {
- $tasksBlockEnd = self::TASKS_BLOCK_END;
- if (defined('BP')) {
- $tasksBlockEnd .= ' ' . md5(BP);
- }
- return $tasksBlockEnd;
- }
- /**
- * {@inheritdoc}
- */
- public function getTasks()
- {
- $this->checkSupportedOs();
- $content = $this->getCrontabContent();
- $pattern = '!(' . $this->getTasksBlockStart() . ')(.*?)(' . $this->getTasksBlockEnd() . ')!s';
- if (preg_match($pattern, $content, $matches)) {
- $tasks = trim($matches[2], PHP_EOL);
- $tasks = explode(PHP_EOL, $tasks);
- return $tasks;
- }
- return [];
- }
- /**
- * {@inheritdoc}
- */
- public function saveTasks(array $tasks)
- {
- if (!$tasks) {
- throw new LocalizedException(new Phrase('The list of tasks is empty. Add tasks and try again.'));
- }
- $this->checkSupportedOs();
- $baseDir = $this->filesystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath();
- $logDir = $this->filesystem->getDirectoryRead(DirectoryList::LOG)->getAbsolutePath();
- foreach ($tasks as $key => $task) {
- if (empty($task['expression'])) {
- $tasks[$key]['expression'] = '* * * * *';
- }
- if (empty($task['command'])) {
- throw new LocalizedException(new Phrase("The command shouldn't be empty. Enter and try again."));
- }
- $tasks[$key]['command'] = str_replace(
- ['{magentoRoot}', '{magentoLog}'],
- [$baseDir, $logDir],
- $task['command']
- );
- }
- $content = $this->getCrontabContent();
- $content = $this->cleanMagentoSection($content);
- $content = $this->generateSection($content, $tasks);
- $this->save($content);
- }
- /**
- * {@inheritdoc}
- * @throws LocalizedException
- */
- public function removeTasks()
- {
- $this->checkSupportedOs();
- $content = $this->getCrontabContent();
- $content = $this->cleanMagentoSection($content);
- $this->save($content);
- }
- /**
- * Generate Magento Tasks Section
- *
- * @param string $content
- * @param array $tasks
- * @return string
- */
- private function generateSection($content, $tasks = [])
- {
- if ($tasks) {
- // Add EOL symbol to previous line if not exist.
- if (substr($content, -strlen(PHP_EOL)) !== PHP_EOL) {
- $content .= PHP_EOL;
- }
- $content .= $this->getTasksBlockStart() . PHP_EOL;
- foreach ($tasks as $task) {
- $content .= $task['expression'] . ' ' . PHP_BINARY . ' ' . $task['command'] . PHP_EOL;
- }
- $content .= $this->getTasksBlockEnd() . PHP_EOL;
- }
- return $content;
- }
- /**
- * Clean Magento Tasks Section in crontab content
- *
- * @param string $content
- * @return string
- */
- private function cleanMagentoSection($content)
- {
- $content = preg_replace(
- '!' . preg_quote($this->getTasksBlockStart()) . '.*?'
- . preg_quote($this->getTasksBlockEnd() . PHP_EOL) . '!s',
- '',
- $content
- );
- return $content;
- }
- /**
- * Get crontab content without Magento Tasks Section
- *
- * In case of some exceptions the empty content is returned
- *
- * @return string
- */
- private function getCrontabContent()
- {
- try {
- $content = (string)$this->shell->execute('crontab -l');
- } catch (LocalizedException $e) {
- return '';
- }
- return $content;
- }
- /**
- * Save crontab
- *
- * @param string $content
- * @return void
- * @throws LocalizedException
- */
- private function save($content)
- {
- $content = str_replace(['%', '"'], ['%%', '\"'], $content);
- try {
- $this->shell->execute('echo "' . $content . '" | crontab -');
- } catch (LocalizedException $e) {
- throw new LocalizedException(
- new Phrase('Error during saving of crontab: %1', [$e->getPrevious()->getMessage()]),
- $e
- );
- }
- }
- /**
- * Check that OS is supported
- *
- * If OS is not supported then no possibility to work with crontab
- *
- * @return void
- * @throws LocalizedException
- */
- private function checkSupportedOs()
- {
- if (stripos(PHP_OS, 'WIN') === 0) {
- throw new LocalizedException(
- new Phrase('Your operating system is not supported to work with this command')
- );
- }
- }
- }
|