Source of file BackgroundTask.php
Size: 4,664 Bytes - Last Modified: 2021-12-24T05:19:33+00:00
/var/www/docs.ssmods.com/process/src/src/Model/BackgroundTask.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 | <?php namespace TractorCow\WebConsole\Model; use BadMethodCallException; use SilverStripe\Assets\Filesystem; use SilverStripe\Core\Path; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\FieldType\DBDatetime; use SilverStripe\ORM\ValidationException; use SilverStripe\Security\Member; use SilverStripe\Security\Permission; /** * Represents a task that runs in the background * * @property string $Status * @property string $Command * @property string $Path * @property string $Output * @property int $ExitCode * @property int $StartedByID * @property string $Started * @property string $Finished * @method Member StartedBy() */ class BackgroundTask extends DataObject { private static $table_name = 'WebConsole_BackgroundTask'; const READY = 'Ready'; const STARTED = 'Started'; const FINISHED = 'Finished'; private static $default_sort = '"WebConsole_BackgroundTask"."ID" DESC'; private static $db = [ 'Status' => "Enum('Ready,Started,Finished','Ready')", 'Command' => 'Text', // Command 'Path' => 'Text', // CWD 'Output' => 'Text', // Output 'Started' => 'DBDatetime', 'Finished' => 'DBDatetime', 'ExitCode' => 'Int', // Response integer (0 is success) ]; private static $has_one = [ 'StartedBy' => Member::class, ]; private static $summary_fields = [ 'Command' => 'Command', 'Created' => 'Created', 'NiceStatus' => 'Status', 'Duration' => 'Duration (h:m:s)' ]; private static $defaults = [ 'Status' => 'Ready', ]; public function getTitle() { return $this->Command; } public function getNiceStatus() { if ($this->Status === self::FINISHED) { return $this->ExitCode ? 'Finished (error)' : 'Finished (success)'; } return $this->Status; } public function getDuration() { if ($this->Status !== self::FINISHED) { return null; } $seconds = $this->dbObject('Finished')->getTimestamp() - $this->dbObject('Started')->getTimestamp(); if (!$seconds) { return null; } // Lazy time calc $secs = $seconds % 60; $minutes = ($seconds - $secs) / 60; $mins = $minutes % 60; $hours = ($minutes - $mins) / 60; // Relative time return "{$hours}:{$mins}:{$secs}"; } /** * Get path to output file. * * Note: This file is deleted once the task is complete * * @return string */ public function getOutputPath() { if (!$this->ID) { return null; } // Ensure standard folder exists $folder = Path::join(ASSETS_PATH, '.protected/_consoletasks'); Filesystem::makeFolder($folder); // Background task writes to filesystem folder $filename = 'output_' . $this->ID . '.txt'; return Path::join(ASSETS_PATH, '.protected/_consoletasks', $filename); } /** * @return string */ public function getOutput() { $output = $this->getField('Output'); if ($output) { return $output; } $path = $this->getOutputPath(); if ($path && file_exists($path)) { return file_get_contents($path); } } /** * Start a task * * @throws ValidationException */ public function start() { if ($this->Status !== self::READY) { throw new BadMethodCallException('Cannot start a task unless it is Ready'); } $this->Started = DBDatetime::now()->getValue(); $this->Status = self::STARTED; $this->write(); } /** * Mark this task as complete * * @param int $code Execution code * @throws ValidationException */ public function complete($code) { // Record exit status $this->ExitCode = $code; $this->Finished = DBDatetime::now()->getValue(); $this->Status = self::FINISHED; // Migrate file content to output field, then delete the file path $path = $this->getOutputPath(); if (file_exists($path)) { $this->Output = file_get_contents($path); $this->write(); // Unlink after write unlink($path); return; } $this->write(); } public function canEdit($member = null) { return false; } public function canDelete($member = null) { return Permission::checkMember($member, 'ADMIN'); } } |