Skip to content

Commit

Permalink
Feature review for various features.
Browse files Browse the repository at this point in the history
  • Loading branch information
mfendeksilverstripe committed Jun 14, 2020
1 parent b362687 commit 1c53d19
Show file tree
Hide file tree
Showing 20 changed files with 1,497 additions and 0 deletions.
70 changes: 70 additions & 0 deletions src/Queue/Admin/DataExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace App\Queue\Admin;

use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\LiteralField;
use SilverStripe\Forms\TextareaField;
use SilverStripe\ORM\DataExtension as BaseDataExtension;
use Symbiote\QueuedJobs\DataObjects\QueuedJobDescriptor;

/**
* Class DataExtension
*
* @property QueuedJobDescriptor|$this $owner
* @package App\Queue\Admin
*/
class DataExtension extends BaseDataExtension
{

/**
* @param FieldList $fields
*/
public function updateCMSFields(FieldList $fields): void
{
$owner = $this->owner;

$fields->addFieldsToTab('Root.JobData', [
$jobDataPreview = TextareaField::create('SavedJobDataPreview', 'Job Data'),
]);

if (strlen($owner->getMessagesRaw()) > 0) {
$fields->addFieldToTab(
'Root.MessagesRaw',
$messagesRaw = LiteralField::create('MessagesRaw', $owner->getMessagesRaw())
);
}

$jobDataPreview->setReadonly(true);
}

/**
* @return string|null
*/
public function getSavedJobDataPreview(): ?string
{
return $this->owner->SavedJobData;
}

/**
* @return string|null
*/
public function getMessagesRaw(): ?string
{
return $this->owner->SavedJobMessages;
}

/**
* @return string
*/
public function getImplementationSummary(): string
{
$segments = explode('\\', $this->owner->Implementation);

while (count($segments) > 2) {
array_shift($segments);
}

return implode('\\', $segments);
}
}
222 changes: 222 additions & 0 deletions src/Queue/Admin/Extension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
<?php

namespace App\Queue\Admin;

use SilverStripe\Core\Extension as BaseExtension;
use SilverStripe\Forms\DropdownField;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\Forms\GridField\GridFieldDataColumns;
use SilverStripe\Forms\GridField\GridFieldFilterHeader;
use SilverStripe\Forms\GridField\GridFieldPaginator;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\FieldType\DBDatetime;
use Symbiote\QueuedJobs\Controllers\QueuedJobsAdmin;
use Symbiote\QueuedJobs\DataObjects\QueuedJobDescriptor;
use Terraformers\RichFilterHeader\Form\GridField\RichFilterHeader;

/**
* Class Extension
*
* @property QueuedJobsAdmin|$this $owner
* @package App\Queue\Admin
*/
class Extension extends BaseExtension
{

private const SCHEDULED_FILTER_FUTURE = 'future';
private const SCHEDULED_FILTER_PAST = 'past';

/**
* @param Form $form
*/
public function updateEditForm(Form $form): void
{
$fields = $form->Fields();

// there are multiple fields that need to be updated
$fieldNames = [
'QueuedJobDescriptor',
$this->encodeClassName(QueuedJobDescriptor::class),
];

foreach ($fieldNames as $fieldName) {
/** @var GridField $gridField */
$gridField = $fields->fieldByName($fieldName);

if (!$gridField) {
continue;
}

$config = $gridField->getConfig();

// apply custom filters
$this->customiseFilters($config);
}
}

/**
* Customise queued jobs filters UI
*
* @param GridFieldConfig $config
*/
private function customiseFilters(GridFieldConfig $config): void
{
/** @var GridFieldDataColumns $gridFieldColumns */
$gridFieldColumns = $config->getComponentByType(GridFieldDataColumns::class);

$gridFieldColumns->setDisplayFields([
'getImplementationSummary' => 'Type',
'JobTypeString' => 'Queue',
'JobStatus' => 'Status',
'JobTitle' => 'Description',
'Created' => 'Added',
'StartAfter' => 'Scheduled',
'JobFinished' => 'Finished',
]);

$config->removeComponentsByType(GridFieldFilterHeader::class);

$filter = new RichFilterHeader();
$filter
->setFilterConfig([
'getImplementationSummary' => 'Implementation',
'Description' => 'JobTitle',
'Status' => [
'title' => 'JobStatus',
'filter' => 'ExactMatchFilter',
],
'JobTypeString' => [
'title' => 'JobType',
'filter' => 'ExactMatchFilter',
],
'Created' => 'Added',
'StartAfter' => 'Scheduled',
])
->setFilterFields([
'JobType' => $queueType = DropdownField::create(
'',
'',
$this->getQueueTypes()
),
'JobStatus' => $jobStatus = DropdownField::create(
'',
'',
$this->getJobStatuses()
),
'Added' => $added = DropdownField::create(
'',
'',
$this->getAddedDates()
),
'Scheduled' => $scheduled = DropdownField::create(
'',
'',
[
self::SCHEDULED_FILTER_FUTURE => self::SCHEDULED_FILTER_FUTURE,
self::SCHEDULED_FILTER_PAST => self::SCHEDULED_FILTER_PAST,
]
),
])
->setFilterMethods([
'Added' => static function (DataList $list, $name, $value): DataList {
if ($value) {
$added = DBDatetime::now()->modify($value);

return $list->filter(['Created:LessThanOrEqual' => $added->Rfc2822()]);
}

return $list;
},
'Scheduled' => static function (DataList $list, $name, $value): DataList {
if ($value === static::SCHEDULED_FILTER_FUTURE) {
return $list->filter([
'StartAfter:GreaterThan' => DBDatetime::now()->Rfc2822(),
]);
}

if ($value === static::SCHEDULED_FILTER_PAST) {
return $list->filter([
'StartAfter:LessThanOrEqual' => DBDatetime::now()->Rfc2822(),
]);
}

return $list;
},
]);

foreach ([$jobStatus, $queueType, $added, $scheduled] as $dropDownField) {
/** @var DropdownField $dropDownField */
$dropDownField->setEmptyString('-- select --');
}

$config->addComponent($filter, GridFieldPaginator::class);
}

/**
* Queue types options for drop down field
*
* @return array
*/
private function getQueueTypes(): array
{
/** @var QueuedJobDescriptor $job */
$job = QueuedJobDescriptor::singleton();
$map = $job->getJobTypeValues();
$values = array_values($map);
$keys = [];

foreach (array_keys($map) as $key) {
$keys[] = (int) $key;
}

return array_combine($keys, $values);
}

/**
* All possible job statuses (this list is not exposed by the module)
* intended to be used in a drop down field
*
* @return array
*/
private function getJobStatuses(): array
{
/** @var QueuedJobDescriptor $job */
$job = QueuedJobDescriptor::singleton();
$statuses = $job->getJobStatusValues();

sort($statuses, SORT_STRING);

$statuses = array_combine($statuses, $statuses);

return $statuses;
}

/**
* Encode class name to match the matching CMS field name
*
* @param string $className
* @return string
*/
private function encodeClassName(string $className): string
{
return str_replace('\\', '-', $className);
}

/**
* Date options for added dates drop down field
*
* @return array
*/
private function getAddedDates(): array
{
return [
'-1 day' => '1 day or older',
'-3 day' => '3 days or older',
'-7 day' => '7 days or older',
'-14 day' => '14 days or older',
'-1 month' => '1 month or older',
];
}
}
63 changes: 63 additions & 0 deletions src/Queue/Cleanup/Task.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace App\Queue\Cleanup;

use SilverStripe\Control\HTTPRequest;
use SilverStripe\Dev\BuildTask;
use SilverStripe\ORM\DB;
use SilverStripe\ORM\FieldType\DBDatetime;
use Symbiote\QueuedJobs\DataObjects\QueuedJobDescriptor;
use Symbiote\QueuedJobs\Services\QueuedJob;
use Symbiote\QueuedJobs\Services\QueuedJobService;

/**
* Class Task
*
* Delete all expired completed jobs
*
* @package App\Queue\Cleanup
*/
class Task extends BuildTask
{

private const EXPIRY_HOURS = 24;
private const EXPIRY_LIMIT = 10000;

/**
* @var string
*/
private static $segment = 'queued-jobs-cleanup';

/**
* @var string
*/
protected $description = 'Delete job descriptors that are older than the configured expiry';

/**
* @param HTTPRequest $request
*/
public function run($request): void // phpcs:ignore SlevomatCodingStandard.TypeHints
{
if (QueuedJobService::singleton()->isMaintenanceLockActive()) {
return;
}

$table = QueuedJobDescriptor::config()->get('table_name');

// determine expiry
$expired = DBDatetime::now()->modify(sprintf('-%s hours', self::EXPIRY_HOURS))->Rfc2822();

// Format query
$query = sprintf(
"DELETE FROM `%s` WHERE `JobStatus` = '%s' AND (`JobFinished` <= '%s' OR `JobFinished` IS NULL) LIMIT %d",
$table,
QueuedJob::STATUS_COMPLETE,
$expired,
self::EXPIRY_LIMIT
);

DB::query($query);

echo sprintf('%d job descriptors deleted.', (int) DB::affected_rows());
}
}
Loading

0 comments on commit 1c53d19

Please sign in to comment.