diff --git a/composer.json b/composer.json
index a3b78293..89bed20a 100644
--- a/composer.json
+++ b/composer.json
@@ -30,7 +30,8 @@
"phpunit/phpunit": "^9.6",
"squizlabs/php_codesniffer": "^3",
"silverstripe/standards": "^1",
- "phpstan/extension-installer": "^1.3"
+ "phpstan/extension-installer": "^1.3",
+ "silverstripe-terraformers/embargo-expiry": "^2.0"
},
"extra": {
"expose": [
@@ -40,7 +41,8 @@
]
},
"suggest": {
- "symbiote/silverstripe-queuedjobs": "Allow automated workflow transitions with queued system jobs"
+ "symbiote/silverstripe-queuedjobs": "Allow automated workflow transitions with queued system jobs",
+ "silverstripe-terraformers/embargo-expiry": "Allow automated workflow transitions with embargo & expiry dates."
},
"autoload": {
"psr-4": {
diff --git a/docs/en/configuration.md b/docs/en/configuration.md
index 5cf89a5c..420edccc 100644
--- a/docs/en/configuration.md
+++ b/docs/en/configuration.md
@@ -17,7 +17,7 @@ extending from `ModelAdmin`. `mysite/_config/config.yml`:
extensions:
- AdvancedWorkflowExtension
-We strongly recommend also setting the `NotifyUsersWorkflowAction` configuration parameter `whitelist_template_variables`
+We strongly recommend also setting the `NotifyUsersWorkflowAction` configuration parameter `whitelist_template_variables`
to true on new projects. This configuration will achieve this:
:::yml
@@ -27,23 +27,22 @@ to true on new projects. This configuration will achieve this:
See the Security section below for more details.
### Embargo and Expiry
-This add-on functionality allows you to embargo some content changes to only appear as published at some future date. To enable it,
-add the `WorkflowEmbargoExpiryExtension`.
- :::yml
- SiteTree:
- extensions:
- - WorkflowEmbargoExpiryExtension
+You can optionally add the [Embargy & Expiry](https://github.com/silverstripe-terraformers/silverstripe-embargo-expiry)
+module to your project to allow changes to be published (and/or unpublished) at future dates.
+
+**Note:** You will need to use version 1.2.1 or greater.
-Make sure the [QueuedJobs](https://github.com/nyeholt/silverstripe-queuedjobs)
-module is installed and configured correctly.
-You should have a cronjob similar to the following in place, running
-as the webserver user.
+#### Migrating from an older Workflow version
- */1 * * * * cd && sudo -u www php /var/www/framework/cli-script.php dev/tasks/ProcessJobQueueTask
+If you have an existing project which used the `WorkflowEmbargoExpiryExtension`, then you will need to go through a
+couple of migration steps.
-It also allows for an optional subsequent expiry date. Note: Changes to these dates also constitute modifications to the content and as such
-are subject to the same workflow approval processes, where a particular workflow instance is in effect. The embargo export functionality can also be used independently of any workflow.
+1) Update usages of `WorkflowEmbargoExpiryExtension` to `EmbargoExpiryExtension` (from the Terraformers module)
+2) Run the `EmbargoExpiryMigrationTask` to migrate over any existing Workflow jobs to the new Terraformers' jobs
+ * This task will require you to define some basic configuration where you tell us what classes you have applied the
+ `EmbargoExpiryExtension` to. Other than that, you just need to run it
+ * See the class for more info
### Sending reminder emails
@@ -57,4 +56,4 @@ Periodically run the Workflow Reminder Task by adding a task like this one to th
This is an example only. The key is to run the task as the same user as the web server.
-You can run the task manually for testing by visiting the `/dev/tasks/WorkflowReminderTask` URL of your site.
\ No newline at end of file
+You can run the task manually for testing by visiting the `/dev/tasks/WorkflowReminderTask` URL of your site.
diff --git a/lang/ar.yml b/lang/ar.yml
index 096c80e6..e9bc02bf 100644
--- a/lang/ar.yml
+++ b/lang/ar.yml
@@ -161,18 +161,8 @@ ar:
WORKFLOW: 'سير العمل'
WORKFLOWACTIVEIINSTANCES: 'أمثلة مهام سير العمل النشطة'
WORKFLOWCOMPLETEDIINSTANCES: 'حالات مهام سير العمل المكتملة'
- WorkflowEmbargoExpiryExtension:
ActiveWorkflowStateTitle: نشط
CompletedWorkflowStateTitle: أكتمل
- PUBLISH_ON: 'موعد النشر المحدد'
- REQUESTED_PUBLISH_DATE: 'موعد النشر المطلوب'
- REQUESTED_PUBLISH_DATE_H3: 'انتهاء الصلاحية و الحظر'
- REQUESTED_PUBLISH_DATE_INTRO: 'قم بإدخال تاريخ و/أو وقت لتحديد موعد الحظر و مواعيد انتهاء الصلاحية.'
- REQUESTED_PUBLISH_DATE_INTRO_BULLET_1: 'هذه الإعدادات لن تنفذ حتى يتم اتخاذ إجراءات الموافقة'
- REQUESTED_PUBLISH_DATE_INTRO_BULLET_2: 'إذا تم بالفعل تطبيق الحظر, فإن إضافة موعد حظر جديد قبل هذا الموعد سوف يقوم باستبدال هذا الموعد'
- REQUESTED_UNPUBLISH_DATE: 'موعد مطلوب لعدم النشر'
- TabTitle: 'نشر الجدول الزمني'
- UNPUBLISH_ON: 'موعد محدد لعد النشر'
WorkflowField:
AddTransitionAction: 'أضف انتقال'
CreateAction: 'قم بعمل نشاط'
diff --git a/lang/de.yml b/lang/de.yml
index 3a1ad6fb..fd88686f 100644
--- a/lang/de.yml
+++ b/lang/de.yml
@@ -155,16 +155,11 @@ de:
WORKFLOW: Arbeitsablauf
WORKFLOWACTIVEIINSTANCES: 'Aktive Arbeitsablaufinstanzen'
WORKFLOWCOMPLETEDIINSTANCES: 'Abgeschlossene Arbeitsablaufinstanzen'
+ ActiveWorkflowStateTitle: Aktiv
+ CompletedWorkflowStateTitle: Fertiggestellt
WorkflowDefinitionImporter:
INVALID_YML_FORMAT_NO_HEADER: 'Ungültiges YAML-Format.'
INVALID_YML_FORMAT_NO_PARSE: 'Ungültiges YAML-Format. Kann nicht eingelesen werden.'
- WorkflowEmbargoExpiryExtension:
- ActiveWorkflowStateTitle: Aktiv
- CompletedWorkflowStateTitle: Fertiggestellt
- PUBLISH_ON: 'Geplantes Veröffentlichungsdatum'
- REQUESTED_PUBLISH_DATE: 'Gewünschtes Veröffentlichungsdatum'
- REQUESTED_PUBLISH_DATE_H3: 'Ablauf und Embargo'
- TabTitle: Veröffentlichungsplan
WorkflowField:
AddTransitionAction: 'Übergang hinzufügen'
CreateAction: 'Aktion erstellen'
diff --git a/lang/en.yml b/lang/en.yml
index 7a722582..97ff869b 100755
--- a/lang/en.yml
+++ b/lang/en.yml
@@ -213,14 +213,6 @@ en:
Symbiote\AdvancedWorkflow\Extensions\WorkflowApplicable:
has_one_WorkflowDefinition: 'Workflow definition'
many_many_AdditionalWorkflowDefinitions: 'Additional workflow definitions'
- Symbiote\AdvancedWorkflow\Extensions\WorkflowEmbargoExpiryExtension:
- db_AllowEmbargoedEditing: 'Allow embargoed editing'
- db_DesiredPublishDate: 'Desired publish date'
- db_DesiredUnPublishDate: 'Desired un publish date'
- db_PublishOnDate: 'Publish on date'
- db_UnPublishOnDate: 'Un publish on date'
- has_one_PublishJob: 'Publish job'
- has_one_UnPublishJob: 'Un publish job'
Symbiote\AdvancedWorkflow\Forms\GridField\GridFieldExportAction:
Export: Export
UnpublishItemWorkflowAction:
@@ -269,28 +261,11 @@ en:
WORKFLOW: Workflow
WORKFLOWACTIVEIINSTANCES: 'Active Workflow Instances'
WORKFLOWCOMPLETEDIINSTANCES: 'Completed Workflow Instances'
+ ActiveWorkflowStateTitle: Active
+ CompletedWorkflowStateTitle: Completed
WorkflowDefinitionImporter:
INVALID_YML_FORMAT_NO_HEADER: 'Invalid YAML format.'
INVALID_YML_FORMAT_NO_PARSE: 'Invalid YAML format. Unable to parse.'
- WorkflowEmbargoExpiryExtension:
- ActiveWorkflowStateTitle: Active
- BADGE_PUBLISH: Embargo
- BADGE_PUBLISH_UNPUBLISH: Embargo+Expiry
- BADGE_UNPUBLISH: Expiry
- CompletedWorkflowStateTitle: Completed
- INVALIDEXPIRY: 'The unpublish date cannot be before the publish date.'
- INVALIDSAMEEMBARGOEXPIRY: 'The publish date and unpublish date cannot be the same.'
- PUBLISH_ON: 'Scheduled publish date'
- REQUESTED_PUBLISH_DATE: 'Requested publish date'
- REQUESTED_PUBLISH_DATE_H3: 'Expiry and Embargo'
- REQUESTED_PUBLISH_DATE_INTRO: 'Enter a date and/or time to specify embargo and expiry dates.'
- REQUESTED_PUBLISH_DATE_INTRO_BULLET_1: "These settings won't take effect until any approval actions are run"
- REQUESTED_PUBLISH_DATE_INTRO_BULLET_2: "If an embargo is already set, adding a new one prior to that date's passing will overwrite it"
- REQUESTED_PUBLISH_DATE_RIGHT_TITLE: 'To request this page to be published immediately leave the date and time fields blank'
- REQUESTED_UNPUBLISH_DATE: 'Requested un-publish date'
- REQUESTED_UNPUBLISH_DATE_RIGHT_TITLE: 'To request this page to never expire leave the date and time fields blank'
- TabTitle: 'Publishing Schedule'
- UNPUBLISH_ON: 'Scheduled un-publish date'
WorkflowField:
AddTransitionAction: 'Add Transition'
CreateAction: 'Create an action'
diff --git a/lang/eo.yml b/lang/eo.yml
index 54bd691a..204a89dc 100644
--- a/lang/eo.yml
+++ b/lang/eo.yml
@@ -213,14 +213,6 @@ eo:
Symbiote\AdvancedWorkflow\Extensions\WorkflowApplicable:
has_one_WorkflowDefinition: 'Laborflua difino'
many_many_AdditionalWorkflowDefinitions: 'Kromaj laborfluoj'
- Symbiote\AdvancedWorkflow\Extensions\WorkflowEmbargoExpiryExtension:
- db_AllowEmbargoedEditing: 'Permesi embargitan redaktadon'
- db_DesiredPublishDate: 'Dezirata publikiga dato'
- db_DesiredUnPublishDate: 'Dezirata malpublikiga dato'
- db_PublishOnDate: 'Publikigi je dato'
- db_UnPublishOnDate: 'Malpublikigi je dato'
- has_one_PublishJob: 'Publikigi taskon'
- has_one_UnPublishJob: 'Malpublikigi taskon'
Symbiote\AdvancedWorkflow\Forms\GridField\GridFieldExportAction:
Export: Eksporti
UnpublishItemWorkflowAction:
@@ -269,27 +261,11 @@ eo:
WORKFLOW: Laborfluo
WORKFLOWACTIVEIINSTANCES: 'Aktivaj laborfluaj ekzemploj'
WORKFLOWCOMPLETEDIINSTANCES: 'Kompletaj laborfluaj ekzemploj'
+ ActiveWorkflowStateTitle: Aktiva
+ CompletedWorkflowStateTitle: Kompletigita
WorkflowDefinitionImporter:
INVALID_YML_FORMAT_NO_HEADER: 'Nevalida YAML-formato.'
INVALID_YML_FORMAT_NO_PARSE: 'Nevalida YAML-formato. Ne povas analizi.'
- WorkflowEmbargoExpiryExtension:
- ActiveWorkflowStateTitle: Aktiva
- BADGE_PUBLISH_UNPUBLISH: Embargo+eksvalidiĝo
- BADGE_UNPUBLISH: Eksvalidiĝo
- CompletedWorkflowStateTitle: Kompletigita
- INVALIDEXPIRY: 'La dato de malpublikigo ne povas esti antaŭ la dato de publikigo.'
- INVALIDSAMEEMBARGOEXPIRY: 'La dato de dato de publikigo kaj la dato demalpublikigo ne povas esti samaj.'
- PUBLISH_ON: 'Planita publikiga dato'
- REQUESTED_PUBLISH_DATE: 'Petita publikiga dato'
- REQUESTED_PUBLISH_DATE_H3: 'Malvalidiĝo kaj embargo'
- REQUESTED_PUBLISH_DATE_INTRO: 'Enigu daton kaj/aŭ horon por agordi embargan kaj malvalidiĝan datojn.'
- REQUESTED_PUBLISH_DATE_INTRO_BULLET_1: 'Tiuj agordoj ekefikos nur kiam eventualaj agoj estas rulitaj'
- REQUESTED_PUBLISH_DATE_INTRO_BULLET_2: 'Se embargo jam estas agordita, aldoni novan antaŭ la paso de ties dato anstataŭos ĝin'
- REQUESTED_PUBLISH_DATE_RIGHT_TITLE: 'Por peti ke ĉi tiu paĝo tuj publikiĝu lasu vakaj la datan kaj horan kampojn'
- REQUESTED_UNPUBLISH_DATE: 'Petita malpublikiga dato'
- REQUESTED_UNPUBLISH_DATE_RIGHT_TITLE: 'Por peti ke ĉi tiu paĝo neniam eksvalidiĝu lasu vakaj la datan kaj horan kampojn'
- TabTitle: 'Publikiga plano'
- UNPUBLISH_ON: 'Planita malpublikiga dato'
WorkflowField:
AddTransitionAction: 'Aldoni transiron'
CreateAction: 'Krei agon'
@@ -300,6 +276,7 @@ eo:
ActionLogTitle: Protokolo
EXECUTE_EXCEPTION: 'Provis startigi nevalidan laborfluan ekzemplon #%s!'
REASSIGN_HEADER: 'Reagordi laborfluon'
+ TITLE_FOR_DO: '%s - %s'
TITLE_STUB: 'Ekzemplo #%s el %s'
TargetClassLabel: 'Cela klaso'
TargetIDLabel: Celo
diff --git a/lang/es.yml b/lang/es.yml
index fcef950a..0e86f9c7 100644
--- a/lang/es.yml
+++ b/lang/es.yml
@@ -165,21 +165,11 @@ es:
WORKFLOW: 'Flujo de trabajo'
WORKFLOWACTIVEIINSTANCES: 'Instancias activas de flujo de trabajo'
WORKFLOWCOMPLETEDIINSTANCES: 'Instancias del flujo de trabajo completadas'
+ ActiveWorkflowStateTitle: Activo
+ CompletedWorkflowStateTitle: Completo
WorkflowDefinitionImporter:
INVALID_YML_FORMAT_NO_HEADER: 'Formato YAML inválido.'
INVALID_YML_FORMAT_NO_PARSE: 'Formato YAML inválido. Imposible analizar.'
- WorkflowEmbargoExpiryExtension:
- ActiveWorkflowStateTitle: Activo
- CompletedWorkflowStateTitle: Completo
- PUBLISH_ON: 'Fecha prevista de publicación'
- REQUESTED_PUBLISH_DATE: 'Fecha solicitada de publicación'
- REQUESTED_PUBLISH_DATE_H3: 'Caducidad y Embargo'
- REQUESTED_PUBLISH_DATE_INTRO: 'Ingresar una fecha y/u hora para especificar las fechas de embargo y caducidad.'
- REQUESTED_PUBLISH_DATE_INTRO_BULLET_1: 'Estos parámetros no tendrán efecto hasta que se ejecuten las acciones de aprobación'
- REQUESTED_PUBLISH_DATE_INTRO_BULLET_2: 'Si ya se estableció un embargo, agregar uno nuevo antes que pase esa fecha, lo sobrescribirá.'
- REQUESTED_UNPUBLISH_DATE: 'Fecha solicitada para anular la publicación'
- TabTitle: 'Horario de publicación'
- UNPUBLISH_ON: 'Fecha prevista para anular la publicación'
WorkflowField:
AddTransitionAction: 'Agregar transición'
CreateAction: 'Crear una acción'
diff --git a/lang/fi_FI.yml b/lang/fi_FI.yml
index 3f20dc40..3f9fe553 100644
--- a/lang/fi_FI.yml
+++ b/lang/fi_FI.yml
@@ -58,7 +58,6 @@ fi_FI:
WorkflowDefinition:
DESCRIPTION: Kuvaus
TITLE: Otsikko
- WorkflowEmbargoExpiryExtension:
ActiveWorkflowStateTitle: Aktiivinen
CompletedWorkflowStateTitle: Valmistunut
WorkflowField:
diff --git a/lang/id.yml b/lang/id.yml
index 083fac52..62edf536 100644
--- a/lang/id.yml
+++ b/lang/id.yml
@@ -65,7 +65,6 @@ id:
WorkflowDefinition:
DESCRIPTION: Deskripsi
TITLE: Judul
- WorkflowEmbargoExpiryExtension:
ActiveWorkflowStateTitle: Aktif
WorkflowField:
CreateLabel: Buat
diff --git a/lang/it.yml b/lang/it.yml
index 54de7cf3..3997a124 100644
--- a/lang/it.yml
+++ b/lang/it.yml
@@ -110,12 +110,11 @@ it:
TITLE: Titolo
USERS: 'Ristretto agli Utenti'
WORKFLOW: 'Flusso di lavoro'
+ ActiveWorkflowStateTitle: Attivo
+ CompletedWorkflowStateTitle: Completato
WorkflowDefinitionImporter:
INVALID_YML_FORMAT_NO_HEADER: 'Formatto YAML non valido'
INVALID_YML_FORMAT_NO_PARSE: 'Formatto YAML non valido. Impossibile fare il parse.'
- WorkflowEmbargoExpiryExtension:
- ActiveWorkflowStateTitle: Attivo
- CompletedWorkflowStateTitle: Completato
WorkflowField:
AddTransitionAction: 'Aggiungi Transazione'
CreateAction: 'Crea un azione'
diff --git a/lang/mi.yml b/lang/mi.yml
index 40e9a37d..e523d2f6 100644
--- a/lang/mi.yml
+++ b/lang/mi.yml
@@ -157,18 +157,8 @@ mi:
WORKFLOW: Reremahi
WORKFLOWACTIVEIINSTANCES: 'Ngā Tauira Reremahi Hohe'
WORKFLOWCOMPLETEDIINSTANCES: 'Ngā Tauira Reremahi Oti'
- WorkflowEmbargoExpiryExtension:
ActiveWorkflowStateTitle: Hohe
CompletedWorkflowStateTitle: 'Kua Oti'
- PUBLISH_ON: 'Rā whakaputa kua whakaritea'
- REQUESTED_PUBLISH_DATE: 'I tonoa te rā whakaputa'
- REQUESTED_PUBLISH_DATE_H3: 'Mōnehutanga me te Rāhui'
- REQUESTED_PUBLISH_DATE_INTRO: 'Tāurua he rā, he wā hoki/rānei hei whakarite rā rāhui me te mōnehu.'
- REQUESTED_PUBLISH_DATE_INTRO_BULLET_1: 'Kāore ēnei tautuhinga e whai mana kia whakahaeretia rā anō ngā hohenga whakaaetanga'
- REQUESTED_PUBLISH_DATE_INTRO_BULLET_2: 'Mēnā kua tautuhi kētia tētahi rāhuitanga, ka tuhiruatia mā te tāpiri i te mea hou i mua i te hipa o taua rā'
- REQUESTED_UNPUBLISH_DATE: 'I tonoa te rā wetewhakaputa'
- TabTitle: 'Hōtaka Whakaputa'
- UNPUBLISH_ON: 'Rā wetewhakaputa kua whakaritea'
WorkflowField:
AddTransitionAction: 'Tāpiri Whakawhiti'
CreateAction: 'Hangaia he hohenga'
diff --git a/lang/sv.yml b/lang/sv.yml
index 822a78db..0d96f076 100644
--- a/lang/sv.yml
+++ b/lang/sv.yml
@@ -60,8 +60,6 @@ sv:
WorkflowDefinition:
DESCRIPTION: Beskrivning
TITLE: Titel
- WorkflowEmbargoExpiryExtension:
- BADGE_UNPUBLISH: 'Går ut'
WorkflowField:
CreateLabel: Skapa
DeleteAction: Radera
diff --git a/lang/zh.yml b/lang/zh.yml
index 05b42c29..8dfc76ae 100644
--- a/lang/zh.yml
+++ b/lang/zh.yml
@@ -161,18 +161,8 @@ zh:
WORKFLOW: 工作流
WORKFLOWACTIVEIINSTANCES: 活动的工作流实例
WORKFLOWCOMPLETEDIINSTANCES: 完成的工作流实例
- WorkflowEmbargoExpiryExtension:
ActiveWorkflowStateTitle: 活跃的
CompletedWorkflowStateTitle: 已完成
- PUBLISH_ON: 安排的发布日期
- REQUESTED_PUBLISH_DATE: 请求的发布日期
- REQUESTED_PUBLISH_DATE_H3: 到期和禁止
- REQUESTED_PUBLISH_DATE_INTRO: 欲指定禁止和到期日,请输入一个日期和/或时间。
- REQUESTED_PUBLISH_DATE_INTRO_BULLET_1: 批准动作执行之前,这些设置不会生效
- REQUESTED_PUBLISH_DATE_INTRO_BULLET_2: 如果已经设置了禁令,在该日期之前添加新的可覆盖该设置
- REQUESTED_UNPUBLISH_DATE: 请求未发布的日期
- TabTitle: 发布日程表
- UNPUBLISH_ON: 安排未发布的日期
WorkflowField:
AddTransitionAction: 添加转换
CreateAction: 制定计划
diff --git a/src/Actions/PublishItemWorkflowAction.php b/src/Actions/PublishItemWorkflowAction.php
index 2bbb2286..aa7bf721 100644
--- a/src/Actions/PublishItemWorkflowAction.php
+++ b/src/Actions/PublishItemWorkflowAction.php
@@ -2,17 +2,12 @@
namespace Symbiote\AdvancedWorkflow\Actions;
-use SilverStripe\Forms\CheckboxField;
-use SilverStripe\Forms\FieldGroup;
-use SilverStripe\Forms\LabelField;
use SilverStripe\Forms\NumericField;
use SilverStripe\ORM\DataObject;
+use SilverStripe\Versioned\Versioned;
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction;
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance;
-use Symbiote\AdvancedWorkflow\Extensions\WorkflowEmbargoExpiryExtension;
-use Symbiote\AdvancedWorkflow\Jobs\WorkflowPublishTargetJob;
-use Symbiote\QueuedJobs\Services\AbstractQueuedJob;
-use Symbiote\QueuedJobs\Services\QueuedJobService;
+use Terraformers\EmbargoExpiry\Extension\EmbargoExpiryExtension;
/**
* Publishes an item
@@ -21,17 +16,13 @@
* @license BSD License (http://silverstripe.org/bsd-license/)
* @package advancedworkflow
* @subpackage actions
+ * @property int $PublishDelay
*/
class PublishItemWorkflowAction extends WorkflowAction
{
- private static $db = array(
- 'PublishDelay' => 'Int',
- 'AllowEmbargoedEditing' => 'Boolean',
- );
-
- private static $defaults = array(
- 'AllowEmbargoedEditing' => true
- );
+ private static $db = [
+ 'PublishDelay' => 'Int',
+ ];
private static $icon = 'symbiote/silverstripe-advancedworkflow:images/publish.png';
@@ -39,50 +30,19 @@ class PublishItemWorkflowAction extends WorkflowAction
public function execute(WorkflowInstance $workflow)
{
- if (!$target = $workflow->getTarget()) {
+ $target = $workflow->getTarget();
+
+ if (!$target) {
return true;
}
- if (class_exists(AbstractQueuedJob::class) && $this->PublishDelay) {
- $job = new WorkflowPublishTargetJob($target);
- $days = $this->PublishDelay;
- $after = date('Y-m-d H:i:s', strtotime("+$days days"));
-
- // disable editing, and embargo the delay if using WorkflowEmbargoExpiryExtension
- if ($target->hasExtension(WorkflowEmbargoExpiryExtension::class)) {
- $target->AllowEmbargoedEditing = $this->AllowEmbargoedEditing;
- $target->PublishOnDate = $after;
- $target->write();
- } else {
- singleton(QueuedJobService::class)->queueJob($job, $after);
- }
- } elseif ($target->hasExtension(WorkflowEmbargoExpiryExtension::class)) {
- $target->AllowEmbargoedEditing = $this->AllowEmbargoedEditing;
- // setting future date stuff if needbe
-
- // set this value regardless
- $target->UnPublishOnDate = $target->DesiredUnPublishDate;
- $target->DesiredUnPublishDate = '';
-
- // Publish dates
- if ($target->DesiredPublishDate) {
- // Hand-off desired publish date
- $target->PublishOnDate = $target->DesiredPublishDate;
- $target->DesiredPublishDate = '';
- $target->write();
- } else {
- // Ensure previously modified DesiredUnPublishDate values are written
- $target->write();
- if ($target->hasMethod('publishRecursive')) {
- $target->publishRecursive();
- $this->extend('onAfterWorkflowPublish', $target);
- }
- }
- } else {
- if ($target->hasMethod('publishRecursive')) {
- $target->publishRecursive();
- $this->extend('onAfterWorkflowPublish', $target);
- }
+ if ($this->targetRequestsDelayedAction($target)) {
+ $this->queueEmbargoExpiryJobs($target);
+
+ $target->write();
+ } elseif ($target->hasExtension(Versioned::class)) {
+ /** @var DataObject|Versioned $target */
+ $target->publishRecursive();
}
return true;
@@ -92,15 +52,11 @@ public function getCMSFields()
{
$fields = parent::getCMSFields();
- if (class_exists(AbstractQueuedJob::class)) {
- $fields->addFieldsToTab('Root.Main', [
- CheckboxField::create(
- 'AllowEmbargoedEditing',
- _t(
- __CLASS__ . '.ALLOWEMBARGOEDEDITING',
- 'Allow editing while item is embargoed? (does not apply without embargo)'
- )
- ),
+ // We don't have access to our Target in this context, so we'll just perform a sanity check to see if the
+ // Embargo & Expiry module is (generally) present
+ if (class_exists(EmbargoExpiryExtension::class)) {
+ $fields->addFieldToTab(
+ 'Root.Main',
NumericField::create(
'PublishDelay',
_t('PublishItemWorkflowAction.PUBLICATIONDELAY', 'Publication Delay')
@@ -108,7 +64,7 @@ public function getCMSFields()
__CLASS__ . '.PublicationDelayDescription',
'Delay publiation by the specified number of days'
))
- ]);
+ );
}
return $fields;
@@ -124,4 +80,57 @@ public function canPublishTarget(DataObject $target)
{
return true;
}
+
+ /**
+ * @param DataObject|EmbargoExpiryExtension $target
+ */
+ public function targetRequestsDelayedAction(DataObject $target): bool
+ {
+ // Delayed actions are only supported if the Embargo & Expiry module is present for the Target
+ if (!$this->targetHasEmbargoExpiryModules($target)) {
+ // E&E is not present on the target, so it cannot have delayed actions
+ return false;
+ }
+
+ // Check to see if the Target has requested an embargo or expiry time
+ if ($target->getDesiredPublishDateAsTimestamp() > 0
+ || $target->getDesiredUnPublishDateAsTimestamp() > 0
+ ) {
+ // One (or both) have been requested
+ return true;
+ }
+
+ // For Publish workflow actions, we'll also check if the reviewer set a PublishDelay
+ if ($this->PublishDelay) {
+ return true;
+ }
+
+ // No embargo, expiry, or delay was requested
+ return false;
+ }
+
+ /**
+ * @param DataObject|EmbargoExpiryExtension $target
+ */
+ public function queueEmbargoExpiryJobs(DataObject $target): void
+ {
+ // Can't queue any jobs if we're missing the Embargo & Expiry module
+ if (!$this->targetHasEmbargoExpiryModules($target)) {
+ return;
+ }
+
+ // Queue UnPublishJob if it's required
+ $target->ensureUnPublishJob();
+
+ // Queue PublishJob if it's required. PublishDelay always take priority over DesiredPublishDate, so exit early
+ // if we queue a job here
+ if ($this->PublishDelay) {
+ $target->createOrUpdatePublishJob(strtotime("+{$this->PublishDelay} days"));
+
+ return;
+ }
+
+ // Queue PublishJob if it's required
+ $target->ensurePublishJob();
+ }
}
diff --git a/src/Actions/UnpublishItemWorkflowAction.php b/src/Actions/UnpublishItemWorkflowAction.php
index d3903cfa..6f86ef53 100644
--- a/src/Actions/UnpublishItemWorkflowAction.php
+++ b/src/Actions/UnpublishItemWorkflowAction.php
@@ -6,26 +6,25 @@
use SilverStripe\Forms\LabelField;
use SilverStripe\Forms\NumericField;
use SilverStripe\ORM\DataObject;
+use SilverStripe\Versioned\Versioned;
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction;
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance;
-use Symbiote\AdvancedWorkflow\Extensions\WorkflowEmbargoExpiryExtension;
-use Symbiote\AdvancedWorkflow\Jobs\WorkflowPublishTargetJob;
-use Symbiote\QueuedJobs\Services\AbstractQueuedJob;
-use Symbiote\QueuedJobs\Services\QueuedJobService;
+use Terraformers\EmbargoExpiry\Extension\EmbargoExpiryExtension;
/**
- * Unpublishes an item
+ * Unpublishes an item or approves it for publishing/un-publishing through queued jobs.
*
* @author marcus@symbiote.com.au
* @license BSD License (http://silverstripe.org/bsd-license/)
* @package advancedworkflow
* @subpackage actions
+ * @property int $UnpublishDelay
*/
class UnpublishItemWorkflowAction extends WorkflowAction
{
- private static $db = array(
- 'UnpublishDelay' => 'Int'
- );
+ private static $db = [
+ 'UnpublishDelay' => 'Int',
+ ];
private static $icon = 'symbiote/silverstripe-advancedworkflow:images/unpublish.png';
@@ -33,30 +32,19 @@ class UnpublishItemWorkflowAction extends WorkflowAction
public function execute(WorkflowInstance $workflow)
{
- if (!$target = $workflow->getTarget()) {
+ $target = $workflow->getTarget();
+
+ if (!$target) {
return true;
}
- if (class_exists(AbstractQueuedJob::class) && $this->UnpublishDelay) {
- $job = new WorkflowPublishTargetJob($target, "unpublish");
- $days = $this->UnpublishDelay;
- $after = date('Y-m-d H:i:s', strtotime("+$days days"));
- singleton(QueuedJobService::class)->queueJob($job, $after);
- } elseif ($target->hasExtension(WorkflowEmbargoExpiryExtension::class)) {
- // setting future date stuff if needbe
-
- // set these values regardless
- $target->DesiredUnPublishDate = '';
- $target->DesiredPublishDate = '';
- $target->write();
+ if ($this->targetRequestsDelayedAction($target)) {
+ $this->queueEmbargoExpiryJobs($target);
- if ($target->hasMethod('doUnpublish')) {
- $target->doUnpublish();
- }
- } else {
- if ($target->hasMethod('doUnpublish')) {
- $target->doUnpublish();
- }
+ $target->write();
+ } elseif ($target->hasExtension(Versioned::class)) {
+ /** @var DataObject|Versioned $target */
+ $target->doUnpublish();
}
return true;
@@ -66,7 +54,9 @@ public function getCMSFields()
{
$fields = parent::getCMSFields();
- if (class_exists(AbstractQueuedJob::class)) {
+ // We don't have access to our Target in this context, so we'll just perform a sanity check to see if the
+ // Embargo & Expiry module is (generally) present
+ if (class_exists(EmbargoExpiryExtension::class)) {
$before = _t('UnpublishItemWorkflowAction.DELAYUNPUBDAYSBEFORE', 'Delay unpublishing by ');
$after = _t('UnpublishItemWorkflowAction.DELAYUNPUBDAYSAFTER', ' days');
@@ -89,4 +79,51 @@ public function canPublishTarget(DataObject $target)
{
return false;
}
+
+ /**
+ * @param DataObject|EmbargoExpiryExtension $target
+ */
+ public function targetRequestsDelayedAction(DataObject $target)
+ {
+ if (!$this->targetHasEmbargoExpiryModules($target)) {
+ return false;
+ }
+
+ if ($target->getDesiredPublishDateAsTimestamp() > 0
+ || $target->getDesiredUnPublishDateAsTimestamp() > 0
+ ) {
+ return true;
+ }
+
+ if ($this->UnpublishDelay) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @param DataObject|EmbargoExpiryExtension $target
+ */
+ public function queueEmbargoExpiryJobs(DataObject $target): void
+ {
+ // Can't queue any jobs if we're missing the Embargo & Expiry module
+ if (!$this->targetHasEmbargoExpiryModules($target)) {
+ return;
+ }
+
+ // Queue PublishJob if it's required
+ $target->ensurePublishJob();
+
+ // Queue UnPublishJob if it's required. UnpublishDelay always take priority over DesiredUnPublishDate, so exit
+ // early if we queue a job here
+ if ($this->UnpublishDelay) {
+ $target->createOrUpdateUnPublishJob(strtotime("+{$this->UnpublishDelay} days"));
+
+ return;
+ }
+
+ // Queue UnPublishJob if it's required
+ $target->ensureUnPublishJob();
+ }
}
diff --git a/src/DataObjects/WorkflowAction.php b/src/DataObjects/WorkflowAction.php
index d962f6a7..a800347e 100644
--- a/src/DataObjects/WorkflowAction.php
+++ b/src/DataObjects/WorkflowAction.php
@@ -16,6 +16,7 @@
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
+use Terraformers\EmbargoExpiry\Extension\EmbargoExpiryExtension;
/**
* A workflow action describes a the 'state' a workflow can be in, and
@@ -310,4 +311,13 @@ public function Icon()
$icon = $this->config()->get('icon');
return ModuleResourceLoader::singleton()->resolveURL($icon);
}
+
+ public function targetHasEmbargoExpiryModules(?DataObject $target): bool
+ {
+ if (!$target) {
+ return false;
+ }
+
+ return $target->hasExtension(EmbargoExpiryExtension::class);
+ }
}
diff --git a/src/DataObjects/WorkflowDefinition.php b/src/DataObjects/WorkflowDefinition.php
index 3c10baac..45c66860 100644
--- a/src/DataObjects/WorkflowDefinition.php
+++ b/src/DataObjects/WorkflowDefinition.php
@@ -382,13 +382,13 @@ public function getCMSFields()
$fields->findOrMakeTab(
'Root.Active',
- _t('WorkflowEmbargoExpiryExtension.ActiveWorkflowStateTitle', 'Active')
+ _t('WorkflowDefinition.ActiveWorkflowStateTitle', 'Active')
);
$fields->addFieldToTab('Root.Active', $active);
$fields->findOrMakeTab(
'Root.Completed',
- _t('WorkflowEmbargoExpiryExtension.CompletedWorkflowStateTitle', 'Completed')
+ _t('WorkflowDefinition.CompletedWorkflowStateTitle', 'Completed')
);
$fields->addFieldToTab('Root.Completed', $completed);
}
diff --git a/src/Extensions/WorkflowApplicable.php b/src/Extensions/WorkflowApplicable.php
index 65142a95..37a84595 100644
--- a/src/Extensions/WorkflowApplicable.php
+++ b/src/Extensions/WorkflowApplicable.php
@@ -27,7 +27,8 @@
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition;
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance;
use Symbiote\AdvancedWorkflow\Services\WorkflowService;
-use Symbiote\QueuedJobs\Services\AbstractQueuedJob;
+use Terraformers\EmbargoExpiry\Extension\EmbargoExpiryExtension;
+use Terraformers\EmbargoExpiry\Job\State\ActionProcessingState;
/**
* DataObjects that have the WorkflowApplicable extension can have a
@@ -37,7 +38,8 @@
* @author marcus@symbiote.com.au
* @license BSD License (http://silverstripe.org/bsd-license/)
* @package advancedworkflow
- *
+ * @property DataObject|EmbargoExpiryExtension|$this $owner
+ * @property int $WorkflowDefinitionID
* @method WorkflowDefinition WorkflowDefinition()
* @method ManyManyList AdditionalWorkflowDefinitions()
*
@@ -57,49 +59,12 @@ class WorkflowApplicable extends DataExtension
'workflowService' => '%$' . WorkflowService::class,
];
- /**
- *
- * Used to flag to this extension if there's a WorkflowPublishTargetJob running.
- * @var boolean
- */
- public $isPublishJobRunning = false;
-
- /**
- *
- * @param boolean $truth
- */
- public function setIsPublishJobRunning($truth)
- {
- $this->isPublishJobRunning = $truth;
- }
-
- /**
- *
- * @return boolean
- */
- public function getIsPublishJobRunning()
- {
- return $this->isPublishJobRunning;
- }
-
- /**
- *
- * @see {@link $this->isPublishJobRunning}
- * @return boolean
- */
- public function isPublishJobRunning()
- {
- $propIsSet = (bool) $this->getIsPublishJobRunning();
- return class_exists(AbstractQueuedJob::class) && $propIsSet;
- }
-
/**
* @var WorkflowService
*/
public $workflowService;
/**
- *
* A cache var for the current workflow instance
*
* @var WorkflowInstance
@@ -128,7 +93,7 @@ public function updateCMSFields(FieldList $fields)
public function updateFields(FieldList $fields)
{
if (!$this->owner->ID) {
- return $fields;
+ return;
}
$tab = $fields->fieldByName('Root') ? $fields->findOrMakeTab('Root.Workflow') : $fields;
@@ -328,8 +293,9 @@ public function LinkToPendingItems()
public function onAfterWrite()
{
$instance = $this->getWorkflowInstance();
+
if ($instance && $instance->CurrentActionID) {
- $action = $instance->CurrentAction()->BaseAction()->targetUpdated($instance);
+ $instance->CurrentAction()->BaseAction()->targetUpdated($instance);
}
}
@@ -391,12 +357,13 @@ public function RecentWorkflowComment($limit = 10)
public function canPublish()
{
// Override any default behaviour, to allow queuedjobs to complete
- if ($this->isPublishJobRunning()) {
+ if ($this->isEmbargoExpiryJobRunning()) {
return true;
}
if ($active = $this->getWorkflowInstance()) {
- $publish = $active->canPublishTarget($this->owner);
+ $publish = $active->canPublishTarget();
+
if (!is_null($publish)) {
return $publish;
}
@@ -409,29 +376,46 @@ public function canPublish()
if (!Security::getCurrentUser()) {
return false;
}
+
$member = Security::getCurrentUser();
$canPublish = $definition->canWorkflowPublish($member, $this->owner);
return $canPublish;
}
+
+ // Don't affect the canPublish() result one way or the other
+ return null;
}
/**
* Can only edit content that's NOT in another person's content changeset
*
- * @return bool
+ * @return bool|null
*/
public function canEdit($member)
{
// Override any default behaviour, to allow queuedjobs to complete
- if ($this->isPublishJobRunning()) {
+ if ($this->owner->isEmbargoExpiryJobRunning()) {
return true;
}
if ($active = $this->getWorkflowInstance()) {
return $active->canEditTarget();
}
+
+ // Don't affect the canEdit() result one way or the other
+ return null;
+ }
+
+ public function isEmbargoExpiryJobRunning(): bool
+ {
+ // Can't be running any Embargo/Expiry jobs if the Extension isn't present on the $owner
+ if (!$this->owner->hasExtension(EmbargoExpiryExtension::class)) {
+ return false;
+ }
+
+ return ActionProcessingState::singleton()->getActionIsProcessing();
}
/**
@@ -442,9 +426,11 @@ public function canEdit($member)
public function canEditWorkflow()
{
$active = $this->getWorkflowInstance();
+
if ($active) {
return $active->canEdit();
}
+
return false;
}
@@ -455,6 +441,7 @@ public function canEditWorkflow()
public function setWorkflowService(WorkflowService $workflowService)
{
$this->workflowService = $workflowService;
+
return $this;
}
@@ -465,4 +452,16 @@ public function getWorkflowService()
{
return $this->workflowService;
}
+
+ public function preventEmbargoExpiryQueueJobs(): bool
+ {
+ // If there is an active WorkflowInstance, then we don't want to allow Embargo & Expiry to queue jobs. We'll do
+ // that ourselves later
+ if ($this->getWorkflowInstance()) {
+ return true;
+ }
+
+ // Similarly, if there is any assigned WorkflowDefinition, then we don't want to queue Jobs in this way
+ return (bool) $this->getWorkflowService()->getDefinitionFor($this->owner);
+ }
}
diff --git a/src/Extensions/WorkflowEmbargoExpiryExtension.php b/src/Extensions/WorkflowEmbargoExpiryExtension.php
deleted file mode 100644
index d05242c8..00000000
--- a/src/Extensions/WorkflowEmbargoExpiryExtension.php
+++ /dev/null
@@ -1,587 +0,0 @@
-
- */
-class WorkflowEmbargoExpiryExtension extends DataExtension
-{
- private static $db = array(
- 'DesiredPublishDate' => 'DBDatetime',
- 'DesiredUnPublishDate' => 'DBDatetime',
- 'PublishOnDate' => 'DBDatetime',
- 'UnPublishOnDate' => 'DBDatetime',
- 'AllowEmbargoedEditing' => 'Boolean',
- );
-
- private static $has_one = array(
- 'PublishJob' => QueuedJobDescriptor::class,
- 'UnPublishJob' => QueuedJobDescriptor::class,
- );
-
- private static $dependencies = array(
- 'workflowService' => '%$' . WorkflowService::class,
- );
-
- private static $defaults = array(
- 'AllowEmbargoedEditing' => true
- );
-
- /**
- * @var WorkflowService
- */
- protected $workflowService;
-
- /**
- * Is a workflow in effect?
- *
- * @var bool
- */
- public $isWorkflowInEffect = false;
-
- /**
- * A basic extended validation routine method return format
- *
- * @var array
- */
- public static $extendedMethodReturn = array(
- 'fieldName' => null,
- 'fieldField' => null,
- 'fieldMsg' => null,
- 'fieldValid' => true,
- );
-
- /**
- * @param FieldList $fields
- */
- public function updateCMSFields(FieldList $fields)
- {
- // requirements
- // ------------
- $module = 'symbiote/silverstripe-advancedworkflow';
- Requirements::add_i18n_javascript($module . ':client/lang');
- Requirements::css($module . ':client/dist/styles/advancedworkflow.css');
- Requirements::javascript($module . ':client/dist/js/advancedworkflow.js');
-
- // Fields
- // ------
-
- // we never show these explicitly in admin
- $fields->removeByName('PublishJobID');
- $fields->removeByName('UnPublishJobID');
-
- $this->setIsWorkflowInEffect();
-
- $fields->findOrMakeTab(
- 'Root.PublishingSchedule',
- _t('WorkflowEmbargoExpiryExtension.TabTitle', 'Publishing Schedule')
- );
- if ($this->getIsWorkflowInEffect()) {
- // add fields we want in this context
- $fields->addFieldsToTab('Root.PublishingSchedule', array(
- HeaderField::create(
- 'PublishDateHeader',
- _t('WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE_H3', 'Expiry and Embargo'),
- 3
- ),
- LiteralField::create('PublishDateIntro', $this->getIntroMessage('PublishDateIntro')),
- $dt = DatetimeField::create(
- 'DesiredPublishDate',
- _t('WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE', 'Requested publish date')
- )->setRightTitle(
- DBHTMLText::create()->setValue(_t(
- 'WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE_RIGHT_TITLE',
- 'To request this page to be published immediately '
- . 'leave the date and time fields blank'
- ))
- ),
- $ut = DatetimeField::create(
- 'DesiredUnPublishDate',
- _t('WorkflowEmbargoExpiryExtension.REQUESTED_UNPUBLISH_DATE', 'Requested un-publish date')
- )->setRightTitle(
- DBHTMLText::create()->setValue(_t(
- 'WorkflowEmbargoExpiryExtension.REQUESTED_UNPUBLISH_DATE_RIGHT_TITLE',
- 'To request this page to never expire leave the date and time fields blank'
- ))
- ),
- DatetimeField::create(
- 'PublishOnDate',
- _t('WorkflowEmbargoExpiryExtension.PUBLISH_ON', 'Scheduled publish date')
- )->setDisabled(true),
- DatetimeField::create(
- 'UnPublishOnDate',
- _t('WorkflowEmbargoExpiryExtension.UNPUBLISH_ON', 'Scheduled un-publish date')
- )->setDisabled(true)
- ));
- } else {
- // remove fields that have been automatically added that we don't want
- $fields->removeByName('DesiredPublishDate');
- $fields->removeByName('DesiredUnPublishDate');
-
- // add fields we want in this context
- $fields->addFieldsToTab('Root.PublishingSchedule', array(
- HeaderField::create(
- 'PublishDateHeader',
- _t('WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE_H3', 'Expiry and Embargo'),
- 3
- ),
- LiteralField::create('PublishDateIntro', $this->getIntroMessage('PublishDateIntro')),
- $dt = DatetimeField::create(
- 'PublishOnDate',
- _t('WorkflowEmbargoExpiryExtension.PUBLISH_ON', 'Scheduled publish date')
- ),
- $ut = DatetimeField::create(
- 'UnPublishOnDate',
- _t('WorkflowEmbargoExpiryExtension.UNPUBLISH_ON', 'Scheduled un-publish date')
- ),
- ));
- }
- }
-
- /**
- * Clears any existing publish job against this dataobject
- */
- public function clearPublishJob()
- {
- $job = $this->owner->PublishJob();
- if ($job && $job->exists() && !$job->JobFinished) {
- $job->delete();
- }
- $this->owner->PublishJobID = 0;
- }
-
- /**
- * Clears any existing unpublish job
- */
- public function clearUnPublishJob()
- {
- // Cancel any in-progress unpublish job
- $job = $this->owner->UnPublishJob();
- if ($job && $job->exists() && !$job->JobFinished) {
- $job->delete();
- }
- $this->owner->UnPublishJobID = 0;
- }
-
- /**
- * Ensure the existence of a publish job at the specified time
- *
- * @param int $when Timestamp to start this job, or null to start immediately
- */
- protected function ensurePublishJob($when)
- {
- // Check if there is a prior job
- if ($this->owner->PublishJobID) {
- $job = $this->owner->PublishJob();
- // Use timestamp for sake of comparison.
- if ($job && $job->exists() && DBDatetime::create()->setValue($job->StartAfter)->getTimestamp() == $when) {
- return;
- }
- $this->clearPublishJob();
- }
-
- // Create a new job with the specified schedule
- $job = new WorkflowPublishTargetJob($this->owner, 'publish');
- $this->owner->PublishJobID = Injector::inst()->get(QueuedJobService::class)
- ->queueJob($job, $when ? date('Y-m-d H:i:s', $when) : null);
- }
-
- /**
- * Ensure the existence of an unpublish job at the specified time
- *
- * @param int $when Timestamp to start this job, or null to start immediately
- */
- protected function ensureUnPublishJob($when)
- {
- // Check if there is a prior job
- if ($this->owner->UnPublishJobID) {
- $job = $this->owner->UnPublishJob();
- // Use timestamp for sake of comparison.
- if ($job && $job->exists() && DBDatetime::create()->setValue($job->StartAfter)->getTimestamp() == $when) {
- return;
- }
- $this->clearUnPublishJob();
- }
-
- // Create a new job with the specified schedule
- $job = new WorkflowPublishTargetJob($this->owner, 'unpublish');
- $this->owner->UnPublishJobID = Injector::inst()->get(QueuedJobService::class)
- ->queueJob($job, $when ? date('Y-m-d H:i:s', $when) : null);
- }
-
- public function onBeforeDuplicate($original, $doWrite)
- {
- $clone = $this->owner;
-
- $clone->PublishOnDate = null;
- $clone->UnPublishOnDate = null;
- $clone->clearPublishJob();
- $clone->clearUnPublishJob();
- }
-
- /**
- * {@see PublishItemWorkflowAction} for approval of requested publish dates
- */
- public function onBeforeWrite()
- {
- parent::onBeforeWrite();
-
- // only operate on staging content for this extension; otherwise, you
- // need to publish the page to be able to set a 'future' publish...
- // while the same could be said for the unpublish, the 'publish' state
- // is the one that must be avoided so we allow setting the 'unpublish'
- // date for as-yet-not-published content.
- if (Versioned::get_stage() === Versioned::LIVE) {
- return;
- }
-
- /*
- * Without checking if there's actually a workflow in effect, simply saving
- * as draft, would clear the Scheduled Publish & Unpublish date fields, which we obviously
- * don't want during a workflow: These date fields should be treated as a content
- * change that also requires approval (where such an approval step exists).
- *
- * - Check to see if we've got 'desired' publish/unpublish date(s).
- * - Check if there's a workflow attached to this content
- * - Reset values if it's safe to do so
- */
- if (!$this->getIsWorkflowInEffect()) {
- $resetPublishOnDate = $this->owner->DesiredPublishDate && $this->owner->PublishOnDate;
- if ($resetPublishOnDate) {
- $this->owner->PublishOnDate = null;
- }
-
- $resetUnPublishOnDate = $this->owner->DesiredUnPublishDate && $this->owner->UnPublishOnDate;
- if ($resetUnPublishOnDate) {
- $this->owner->UnPublishOnDate = null;
- }
- }
-
- // Jobs can only be queued for records that already exist
- if (!$this->owner->ID) {
- return;
- }
-
- if ($this->owner->hasMethod('isPublishJobRunning') && $this->owner->isPublishJobRunning()) {
- return;
- }
-
- // Check requested dates of publish / unpublish, and whether the page should have already been unpublished
- $now = DBDatetime::now()->getTimestamp();
- $publishTime = $this->owner->dbObject('PublishOnDate')->getTimestamp();
- $unPublishTime = $this->owner->dbObject('UnPublishOnDate')->getTimestamp();
-
- // We should have a publish job if:
- // if no unpublish or publish time, then the Workflow Publish Action will publish without a job
- if ((!$unPublishTime && $publishTime) // the unpublish date is not set
- || (
- // unpublish date has not passed
- $unPublishTime > $now
- // publish date not set or happens before unpublish date
- && ($publishTime && ($publishTime < $unPublishTime))
- )
- ) {
- // Trigger time immediately if passed
- $this->ensurePublishJob($publishTime < $now ? null : $publishTime);
- } else {
- $this->clearPublishJob();
- }
-
- // We should have an unpublish job if:
- if ($unPublishTime // we have an unpublish date
- &&
- $publishTime < $unPublishTime // publish date is before to unpublish date
- ) {
- // Trigger time immediately if passed
- $this->ensureUnPublishJob($unPublishTime < $now ? null : $unPublishTime);
- } else {
- $this->clearUnPublishJob();
- }
- }
-
- /**
- * Add badges to the site tree view to show that a page has been scheduled for publishing or unpublishing
- *
- * @param $flags
- */
- public function updateStatusFlags(&$flags)
- {
- $embargo = $this->getIsPublishScheduled();
- $expiry = $this->getIsUnPublishScheduled();
-
- if ($embargo || $expiry) {
- unset($flags['addedtodraft'], $flags['modified']);
- }
-
- if ($embargo && $expiry) {
- $flags['embargo_expiry'] = array(
- 'text' => _t('WorkflowEmbargoExpiryExtension.BADGE_PUBLISH_UNPUBLISH', 'Embargo+Expiry'),
- 'title' => sprintf(
- '%s: %s, %s: %s',
- _t('WorkflowEmbargoExpiryExtension.PUBLISH_ON', 'Scheduled publish date'),
- $this->owner->PublishOnDate,
- _t('WorkflowEmbargoExpiryExtension.UNPUBLISH_ON', 'Scheduled un-publish date'),
- $this->owner->UnPublishOnDate
- ),
- );
- } elseif ($embargo) {
- $flags['embargo'] = array(
- 'text' => _t('WorkflowEmbargoExpiryExtension.BADGE_PUBLISH', 'Embargo'),
- 'title' => sprintf(
- '%s: %s',
- _t('WorkflowEmbargoExpiryExtension.PUBLISH_ON', 'Scheduled publish date'),
- $this->owner->PublishOnDate
- ),
- );
- } elseif ($expiry) {
- $flags['expiry'] = array(
- 'text' => _t('WorkflowEmbargoExpiryExtension.BADGE_UNPUBLISH', 'Expiry'),
- 'title' => sprintf(
- '%s: %s',
- _t('WorkflowEmbargoExpiryExtension.UNPUBLISH_ON', 'Scheduled un-publish date'),
- $this->owner->UnPublishOnDate
- ),
- );
- }
- }
-
- /*
- * Define an array of message-parts for use by {@link getIntroMessage()}
- *
- * @param string $key
- * @return array
- */
- public function getIntroMessageParts($key)
- {
- $parts = array(
- 'PublishDateIntro' => array(
- 'INTRO'=>_t(
- 'WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE_INTRO',
- 'Enter a date and/or time to specify embargo and expiry dates.'
- ),
- 'BULLET_1'=>_t(
- 'WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE_INTRO_BULLET_1',
- 'These settings won\'t take effect until any approval actions are run'
- ),
- 'BULLET_2'=>_t(
- 'WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE_INTRO_BULLET_2',
- 'If an embargo is already set, adding a new one prior to that date\'s passing will overwrite it'
- )
- )
- );
- // If there's no effective workflow, no need for the first bullet-point
- if (!$this->getIsWorkflowInEffect()) {
- $parts['PublishDateIntro']['BULLET_1'] = false;
- }
- return $parts[$key];
- }
-
- /*
- * Display some messages to the user, a little more complex that a simple one-liner
- *
- * @param string $key
- * @return string
- */
- public function getIntroMessage($key)
- {
- $msg = $this->getIntroMessageParts($key);
- $curr = Controller::curr();
- $msg = $curr->customise($msg)->renderWith('Includes/embargoIntro');
- return $msg;
- }
-
- /*
- * Validate
- */
- public function getCMSValidator()
- {
- $required = new AWRequiredFields();
- $required->setCaller($this);
- return $required;
- }
-
- /**
- * This is called in the AWRequiredFields class, this validates whether an Embargo and Expiry are not equal and that
- * Embargo is before Expiry, returning the appropriate message when it fails.
- *
- * @param $data
- * @return array
- */
- public function extendedRequiredFieldsEmbargoExpiry($data)
- {
- $response = array(
- 'fieldName' => 'DesiredUnPublishDate[date]',
- 'fieldField' => null,
- 'fieldMsg' => null,
- 'fieldValid' => true
- );
-
- if (isset($data['DesiredPublishDate'], $data['DesiredUnPublishDate'])) {
- $publish = DBDatetime::create()->setValue($data['DesiredPublishDate'])->getTimestamp();
- $unpublish = DBDatetime::create()->setValue($data['DesiredUnPublishDate'])->getTimestamp();
-
- // the times are the same
- if ($publish && $unpublish && $publish == $unpublish) {
- $response = array_merge($response, array(
- 'fieldMsg' => _t(
- 'WorkflowEmbargoExpiryExtension.INVALIDSAMEEMBARGOEXPIRY',
- 'The publish date and unpublish date cannot be the same.'
- ),
- 'fieldValid' => false
- ));
- } elseif ($publish && $unpublish && $publish > $unpublish) {
- $response = array_merge($response, array(
- 'fieldMsg' => _t(
- 'WorkflowEmbargoExpiryExtension.INVALIDEXPIRY',
- 'The unpublish date cannot be before the publish date.'
- ),
- 'fieldValid' => false
- ));
- }
- }
-
- return $response;
- }
-
- /**
- * Format a date according to member/user preferences
- *
- * @param string $date
- * @return string $date
- */
- public function getUserDate($date)
- {
- $date = DBDatetime::create()->setValue($date);
- $member = Security::getCurrentUser();
- return $date->FormatFromSettings($member);
- }
-
- /*
- * Sets property as boolean true|false if an effective workflow is found or not
- */
- public function setIsWorkflowInEffect()
- {
- // if there is a workflow applied, we can't set the publishing date directly, only the 'desired' publishing date
- $effective = $this->getWorkflowService()->getDefinitionFor($this->owner);
- $this->isWorkflowInEffect = $effective ? true : false;
- }
-
- public function getIsWorkflowInEffect()
- {
- return $this->isWorkflowInEffect;
- }
-
- /**
- * Returns whether a publishing date has been set and is after the current date
- *
- * @return bool
- */
- public function getIsPublishScheduled()
- {
- if (!$this->owner->PublishOnDate) {
- return false;
- }
- $now = DBDatetime::now()->getTimestamp();
- $publish = $this->owner->dbObject('PublishOnDate')->getTimestamp();
-
- return $now < $publish;
- }
-
- /**
- * Returns whether an unpublishing date has been set and is after the current date
- *
- * @return bool
- */
- public function getIsUnPublishScheduled()
- {
- if (!$this->owner->UnPublishOnDate) {
- return false;
- }
- $now = DBDatetime::now()->getTimestamp();
- $unpublish = $this->owner->dbObject('UnPublishOnDate')->getTimestamp();
-
- return $now < $unpublish;
- }
-
- /**
- * Add edit check for when publishing has been scheduled and if any workflow definitions want the item to be
- * disabled.
- *
- * @param Member $member
- * @return bool|null
- */
- public function canEdit($member)
- {
- if (!Permission::check('EDIT_EMBARGOED_WORKFLOW') && // not given global/override permission to edit
- !$this->owner->AllowEmbargoedEditing) { // item flagged as not editable
- $publishTime = $this->owner->dbObject('PublishOnDate');
-
- if ($publishTime && $publishTime->InFuture() || // when scheduled publish date is in the future
- // when there isn't a publish date, but a Job is in place (publish immediately, but queued jobs is
- // waiting)
- (!$publishTime && $this->owner->PublishJobID != 0)
- ) {
- return false;
- }
- }
- }
-
- /**
- * Set the workflow service instance
- *
- * @param WorkflowService $workflowService
- * @return $this
- */
- public function setWorkflowService(WorkflowService $workflowService)
- {
- $this->workflowService = $workflowService;
- return $this;
- }
-
- /**
- * Get the workflow service instance
- *
- * @return WorkflowService
- */
- public function getWorkflowService()
- {
- return $this->workflowService;
- }
-}
diff --git a/src/Jobs/WorkflowPublishTargetJob.php b/src/Jobs/WorkflowPublishTargetJob.php
deleted file mode 100644
index e4bbdf8e..00000000
--- a/src/Jobs/WorkflowPublishTargetJob.php
+++ /dev/null
@@ -1,64 +0,0 @@
-setObject($obj);
- $this->publishType = $type ? strtolower($type) : 'publish';
- $this->totalSteps = 1;
- }
- }
-
- public function getTitle()
- {
- return _t(
- 'AdvancedWorkflowPublishJob.SCHEDULEJOBTITLE',
- "Scheduled {type} of {object}",
- "",
- array(
- 'type' => $this->publishType,
- 'object' => $this->getObject()->Title
- )
- );
- }
-
- public function process()
- {
- if ($target = $this->getObject()) {
- if ($this->publishType == 'publish') {
- $target->setIsPublishJobRunning(true);
- $target->PublishOnDate = '';
- $target->writeWithoutVersion();
- $target->publishRecursive();
- $this->extend('onAfterWorkflowPublish', $target);
- } elseif ($this->publishType == 'unpublish') {
- $target->setIsPublishJobRunning(true);
- $target->UnPublishOnDate = '';
- $target->writeWithoutVersion();
- $target->doUnpublish();
- $this->extend('onAfterWorkflowUnublish', $target);
- }
- }
- $this->currentStep = 1;
- $this->isComplete = true;
- }
-}
diff --git a/src/Tasks/EmbargoExpiryMigrationTask.php b/src/Tasks/EmbargoExpiryMigrationTask.php
new file mode 100644
index 00000000..631767c5
--- /dev/null
+++ b/src/Tasks/EmbargoExpiryMigrationTask.php
@@ -0,0 +1,72 @@
+config()->get('classes') as $className) {
+ if (!DataObject::singleton($className)->hasExtension(EmbargoExpiryExtension::class)) {
+ continue;
+ }
+
+ /** @var DataList|DataObject[]|EmbargoExpiryExtension[] $dataObjects */
+ $dataObjects = DataObject::get($className);
+
+ foreach ($dataObjects as $dataObject) {
+ $updated = false;
+
+ if ($dataObject->PublishOnDate) {
+ $dataObject->createOrUpdatePublishJob(strtotime($dataObject->PublishOnDate));
+
+ $updated = true;
+ }
+
+ if ($dataObject->UnPublishOnDate) {
+ $dataObject->createOrUpdateUnPublishJob(strtotime($dataObject->UnPublishOnDate));
+
+ $updated = true;
+ }
+
+ if ($updated) {
+ $dataObject->write();
+ }
+ }
+ }
+ }
+}
diff --git a/tests/php/WorkflowEmbargoExpiry.yml b/tests/php/WorkflowEmbargoExpiry.yml
index 345932e2..e69de29b 100644
--- a/tests/php/WorkflowEmbargoExpiry.yml
+++ b/tests/php/WorkflowEmbargoExpiry.yml
@@ -1,53 +0,0 @@
-Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition:
- requestPublication:
- Title: 'Request Publish'
- approvePublication:
- Title: 'Approve Publish'
-
-Symbiote\AdvancedWorkflow\Actions\SimpleApprovalWorkflowAction:
- requestPublication:
- Title: 'Approve'
- WorkflowDefID: =>Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition.requestPublication
-
-Symbiote\AdvancedWorkflow\Actions\PublishItemWorkflowAction:
- approvePublication:
- Title: 'Publish'
- WorkflowDefID: =>Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition.approvePublication
-
-SilverStripe\CMS\Model\SiteTree:
- emptyEmbargoExpiry:
- Title: 'Empty embargo and expiry'
- pastEmbargo:
- Title: 'Embargo in the past'
- DesiredPublishDate: 2013-01-15
- pastExpiry:
- Title: 'Expiry in the past'
- DesiredUnPublishDate: 2013-03-15
- pastEmbargoExpiry:
- Title: 'Embargo and expiry in the past'
- DesiredPublishDate: 2013-01-15
- DesiredUnPublishDate: 2013-03-15
- pastEmbargoFutureExpiry:
- Title: 'Embargo in the past and expiry in the future'
- DesiredPublishDate: 2013-01-15
- DesiredUnPublishDate: 2015-03-15
- futureEmbargoExpiry:
- Title: 'Embargo and expiry in the future'
- DesiredPublishDate: 2015-01-15
- DesiredUnPublishDate: 2015-03-15
- pastEmbargoAfterExpiry:
- Title: 'Embargo after expiry in the past'
- DesiredPublishDate: 2013-03-15
- DesiredUnPublishDate: 2013-01-15
- futureEmbargoAfterExpiry:
- Title: 'Embargo after expiry in the future'
- DesiredPublishDate: 2015-03-15
- DesiredUnPublishDate: 2015-01-15
- pastSameEmbargoExpiry:
- Title: 'Embargo and expiry are the same in the past'
- DesiredPublishDate: 2013-01-15
- DesiredUnPublishDate: 2013-01-15
- futureSameEmbargoExpiry:
- Title: 'Embargo and expiry are the same in the future'
- DesiredPublishDate: 2015-01-15
- DesiredUnPublishDate: 2015-01-15
diff --git a/tests/php/WorkflowEmbargoExpiryTest.php b/tests/php/WorkflowEmbargoExpiryTest.php
index 1fd402da..8b399976 100644
--- a/tests/php/WorkflowEmbargoExpiryTest.php
+++ b/tests/php/WorkflowEmbargoExpiryTest.php
@@ -7,17 +7,12 @@
use SilverStripe\Dev\SapphireTest;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\FieldType\DBDatetime;
-use SilverStripe\Translatable\Model\Translatable;
-use SilverStripe\Security\Member;
-use SilverStripe\Subsites\Extensions\SiteTreeSubsites;
use SilverStripe\Versioned\Versioned;
-use Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction;
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition;
-use Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition;
-use Symbiote\AdvancedWorkflow\Extensions\WorkflowEmbargoExpiryExtension;
+use Symbiote\AdvancedWorkflow\Extensions\WorkflowApplicable;
use Symbiote\AdvancedWorkflow\Services\WorkflowService;
-use Symbiote\QueuedJobs\Services\AbstractQueuedJob;
use Symbiote\QueuedJobs\Services\QueuedJobService;
+use Terraformers\EmbargoExpiry\Extension\EmbargoExpiryExtension;
/**
* @author marcus@symbiote.com.au
@@ -25,72 +20,36 @@
*/
class WorkflowEmbargoExpiryTest extends SapphireTest
{
- protected static $fixture_file = 'WorkflowEmbargoExpiry.yml';
+ protected static $fixture_file = 'WorkflowEmbargoExpiryTest.yml';
+
+ protected static $required_extensions = [
+ SiteTree::class => [
+ WorkflowApplicable::class,
+ EmbargoExpiryExtension::class,
+ ],
+ ];
protected function setUp(): void
{
- // Prevent failure if queuedjobs module isn't installed.
- if (!class_exists(AbstractQueuedJob::class)) {
- static::$fixture_file = '';
- parent::setUp();
- $this->markTestSkipped("This test requires queuedjobs");
- }
- parent::setUp();
-
DBDatetime::set_mock_now('2014-01-05 12:00:00');
// This doesn't play nicely with PHPUnit
Config::modify()->set(QueuedJobService::class, 'use_shutdown_function', false);
+
+ parent::setUp();
}
protected function tearDown(): void
{
DBDatetime::clear_mock_now();
- parent::tearDown();
- }
-
- /**
- * @var array
- */
- protected static $required_extensions = array(
- SiteTree::class => array(
- WorkflowEmbargoExpiryExtension::class,
- Versioned::class,
- ),
- );
- /**
- * @var array
- */
- protected static $illegal_extensions = array(
- SiteTree::class => array(
- Translatable::class,
- SiteTreeSubsites::class,
- ),
- );
-
- /**
- * Start a workflow for a page,
- * this will set it into a state where a workflow is currently being processes
- *
- * @param DataObject $obj
- * @return DataObject
- */
- private function startWorkflow($obj)
- {
- $workflow = $this->objFromFixture(WorkflowDefinition::class, 'requestPublication');
- $obj->WorkflowDefinitionID = $workflow->ID;
- $obj->write();
-
- $svc = singleton(WorkflowService::class);
- $svc->startWorkflow($obj, $obj->WorkflowDefinitionID);
- return $obj;
+ parent::tearDown();
}
/**
* Start and finish a workflow which will publish the page immediately basically.
*
- * @param DataObject $obj
+ * @param DataObject|mixed $obj
* @return DataObject
*/
private function finishWorkflow($obj)
@@ -127,362 +86,146 @@ private function getLive($obj)
*
* No jobs should be created, but page is published by the workflow action.
*/
- public function testEmptyEmbargoExpiry()
+ public function testEmptyEmbargoExpiry(): void
{
+ /** @var SiteTree|EmbargoExpiryExtension $page */
$page = $this->objFromFixture(SiteTree::class, 'emptyEmbargoExpiry');
$page->Content = 'Content to go live';
- $live = $this->getLive($page);
-
- $this->assertEmpty($live->Content);
+ // This record should not yet be published.
+ $this->assertFalse($page->isPublished());
$this->assertEquals(0, $page->PublishJobID);
$this->assertEquals(0, $page->UnPublishJobID);
$page = $this->finishWorkflow($page);
+ /** @var SiteTree|EmbargoExpiryExtension $live */
$live = $this->getLive($page);
$this->assertNotEmpty($live->Content);
- $this->assertEquals(0, $page->PublishJobID);
- $this->assertEquals(0, $page->UnPublishJobID);
+ $this->assertEquals(0, $live->PublishJobID);
+ $this->assertEquals(0, $live->UnPublishJobID);
}
/**
- * Test for embargo in the past
+ * Test when both embargo and expiry dates are set.
*
- * Creates a publish job which is queued for immediately
+ * Jobs should be created, and the page should not be published as part of the workflow action.
*/
- public function testPastEmbargo()
+ public function testProcessEmbargoExpiry(): void
{
- $page = $this->objFromFixture(SiteTree::class, 'pastEmbargo');
-
- $page = $this->finishWorkflow($page);
-
- $this->assertNotEquals(0, $page->PublishJobID);
- $this->assertEquals(0, $page->UnPublishJobID);
+ /** @var SiteTree|EmbargoExpiryExtension $page */
+ $page = $this->objFromFixture(SiteTree::class, 'processEmbargoExpiry');
- $publish = strtotime($page->PublishJob()->StartAfter ?? '');
- $this->assertFalse($publish);
- }
-
- /**
- * Test for expiry in the past
- *
- * Creates an unpublish job which is queued for immediately
- */
- public function testPastExpiry()
- {
- $page = $this->objFromFixture(SiteTree::class, 'pastExpiry');
+ $page->Content = 'Content to go live';
+ $page->DesiredPublishDate = '2014-01-06 12:00:00';
+ $page->DesiredUnPublishDate = '2014-01-08 12:00:00';
- $page = $this->finishWorkflow($page);
+ // Jobs would ordinarily be queued at this time, but because we have a Workflow applied (in the fixture), we
+ // should halt that from happening.
+ $page->write();
+ $this->assertNotNull($page->DesiredPublishDate);
+ $this->assertNotNull($page->DesiredUnPublishDate);
+ $this->assertNull($page->PublishOnDate);
+ $this->assertNull($page->UnPublishOnDate);
$this->assertEquals(0, $page->PublishJobID);
- $this->assertNotEquals(0, $page->UnPublishJobID);
-
- $unpublish = strtotime($page->UnPublishJob()->StartAfter ?? '');
-
- $this->assertFalse($unpublish);
- }
-
- /**
- * Test for embargo and expiry in the past
- *
- * Creates an unpublish job which is queued for immediately
- */
- public function testPastEmbargoExpiry()
- {
- $page = $this->objFromFixture(SiteTree::class, 'pastEmbargoExpiry');
+ $this->assertEquals(0, $page->UnPublishJobID);
+ /** @var SiteTree|EmbargoExpiryExtension $page */
$page = $this->finishWorkflow($page);
- $this->assertEquals(0, $page->PublishJobID);
- $this->assertNotEquals(0, $page->UnPublishJobID);
-
- $unpublish = strtotime($page->UnPublishJob()->StartAfter ?? '');
+ // Check that the Jobs have been created, and that the object fields were correctly updated.
+ $this->assertNull($page->DesiredPublishDate);
+ $this->assertNull($page->DesiredUnPublishDate);
+ $this->assertNotNull($page->PublishOnDate);
+ $this->assertNotNull($page->UnPublishOnDate);
+ $this->assertNotNull($page->PublishJob());
+ $this->assertNotNull($page->UnPublishJob());
- $this->assertFalse($unpublish);
+ // This record should not yet be published.
+ $this->assertFalse($page->isPublished());
}
/**
- * Test for embargo in the past and expiry in the future
+ * Test when only an embargo date is set.
*
- * Creates a publish job which is queued for immediately and an unpublish job which is queued for later
- */
- public function testPastEmbargoFutureExpiry()
- {
- $page = $this->objFromFixture(SiteTree::class, 'pastEmbargoFutureExpiry');
-
- $page = $this->finishWorkflow($page);
-
- $this->assertNotEquals(0, $page->PublishJobID);
- $this->assertNotEquals(0, $page->UnPublishJobID);
-
- $publish = strtotime($page->PublishJob()->StartAfter ?? '');
- $unpublish = strtotime($page->UnPublishJob()->StartAfter ?? '');
-
- $this->assertFalse($publish);
- $this->assertNotFalse($unpublish);
- }
-
- /**
- * Test for embargo and expiry in the future
+ * A publish job should be created, and the page should not be published as part of the workflow action.
*
- * Creates a publish and unpublish job which are queued for immediately
+ * No un-publish job should be created.
*/
- public function testFutureEmbargoExpiry()
+ public function testProcessEmbargo(): void
{
- $page = $this->objFromFixture(SiteTree::class, 'futureEmbargoExpiry');
-
- $page = $this->finishWorkflow($page);
-
- $this->assertNotEquals(0, $page->PublishJobID);
- $this->assertNotEquals(0, $page->UnPublishJobID);
-
- $publish = strtotime($page->PublishJob()->StartAfter ?? '');
- $unpublish = strtotime($page->UnPublishJob()->StartAfter ?? '');
+ /** @var SiteTree|EmbargoExpiryExtension $page */
+ $page = $this->objFromFixture(SiteTree::class, 'processEmbargo');
- $this->assertNotFalse($publish);
- $this->assertNotFalse($unpublish);
- }
-
- /**
- * Test for embargo after expiry in the past
- *
- * No jobs should be created, invalid option
- */
- public function testPastEmbargoAfterExpiry()
- {
- $page = $this->objFromFixture(SiteTree::class, 'pastEmbargoAfterExpiry');
+ $page->Content = 'Content to go live';
+ $page->DesiredPublishDate = '2014-01-06 12:00:00';
- $page = $this->finishWorkflow($page);
+ // Jobs would ordinarily be queued at this time, but because we have a Workflow applied (in the fixture), we
+ // should halt that from happening.
+ $page->write();
+ $this->assertNotNull($page->DesiredPublishDate);
+ $this->assertNull($page->DesiredUnPublishDate);
+ $this->assertNull($page->PublishOnDate);
+ $this->assertNull($page->UnPublishOnDate);
$this->assertEquals(0, $page->PublishJobID);
$this->assertEquals(0, $page->UnPublishJobID);
- }
-
- /**
- * Test for embargo after expiry in the future
- *
- * No jobs should be created, invalid option
- */
- public function testFutureEmbargoAfterExpiry()
- {
- $page = $this->objFromFixture(SiteTree::class, 'futureEmbargoAfterExpiry');
+ /** @var SiteTree|EmbargoExpiryExtension $page */
$page = $this->finishWorkflow($page);
- $this->assertEquals(0, $page->PublishJobID);
+ // Check that the Jobs have been created, and that the object fields were correctly updated.
+ $this->assertNull($page->DesiredPublishDate);
+ $this->assertNull($page->DesiredUnPublishDate);
+ $this->assertNotNull($page->PublishOnDate);
+ $this->assertNull($page->UnPublishOnDate);
+ $this->assertTrue($page->PublishJob()->exists());
$this->assertEquals(0, $page->UnPublishJobID);
- }
-
- /**
- * Test for embargo and expiry in the past, both have the same value
- *
- * No jobs should be created, invalid option
- */
- public function testPastSameEmbargoExpiry()
- {
- $page = $this->objFromFixture(SiteTree::class, 'pastSameEmbargoExpiry');
-
- $page = $this->finishWorkflow($page);
- $this->assertEquals(0, $page->PublishJobID);
- $this->assertEquals(0, $page->UnPublishJobID);
+ // This record should not yet be published.
+ $this->assertFalse($page->isPublished());
}
/**
- * Test for embargo and expiry in the future, both have the same value
+ * Test when only an expiry date is set.
*
- * No jobs should be created, invalid option
- */
- public function testFutureSameEmbargoExpiry()
- {
- $page = $this->objFromFixture(SiteTree::class, 'futureSameEmbargoExpiry');
-
- $page = $this->finishWorkflow($page);
-
- $this->assertEquals(0, $page->PublishJobID);
- $this->assertEquals(0, $page->UnPublishJobID);
- }
-
- /**
- * When an item is queued for publishing or unpublishing and new dates are entered
+ * An un-publish job should be created, and the page should not be published as part of the workflow action.
*
- * The existing queued jobs should be cleared
+ * No publish job should be created.
*/
- public function testDesiredRemovesJobs()
+ public function testProcessExpiry(): void
{
- $page = $this->objFromFixture(SiteTree::class, 'futureEmbargoExpiry');
-
- $page = $this->finishWorkflow($page);
-
- $this->assertNotEquals(0, $page->PublishJobID);
- $this->assertNotEquals(0, $page->UnPublishJobID);
+ /** @var SiteTree|EmbargoExpiryExtension $page */
+ $page = $this->objFromFixture(SiteTree::class, 'processExpiry');
- $page->DesiredPublishDate = '2020-02-01 00:00:00';
- $page->DesiredUnPublishDate = '2020-02-01 02:00:00';
+ $page->Content = 'Content to go live';
+ $page->DesiredUnPublishDate = '2014-01-08 12:00:00';
+ // Jobs would ordinarily be queued at this time, but because we have a Workflow applied (in the fixture), we
+ // should halt that from happening.
$page->write();
+ $this->assertNull($page->DesiredPublishDate);
+ $this->assertNotNull($page->DesiredUnPublishDate);
+ $this->assertNull($page->PublishOnDate);
+ $this->assertNull($page->UnPublishOnDate);
$this->assertEquals(0, $page->PublishJobID);
$this->assertEquals(0, $page->UnPublishJobID);
- }
-
- /**
- * Tests that checking for publishing scheduled state is working
- */
- public function testIsPublishScheduled()
- {
- $page = SiteTree::create();
- $page->Title = 'My page';
- $page->PublishOnDate = '2010-01-01 00:00:00';
- $page->AllowEmbargoedEditing = false;
- $page->write();
-
- $this->assertFalse($page->getIsPublishScheduled());
-
- $page->PublishOnDate = '2016-02-01 00:00:00';
- DBDatetime::set_mock_now('2016-01-16 00:00:00');
- $this->assertTrue($page->getIsPublishScheduled());
- DBDatetime::set_mock_now('2016-02-16 00:00:00');
- $this->assertFalse($page->getIsPublishScheduled());
- }
-
- /**
- * Tests that checking for un-publishing scheduled state is working
- */
- public function testIsUnPublishScheduled()
- {
- $page = SiteTree::create();
- $page->Title = 'My page';
- $page->PublishOnDate = '2010-01-01 00:00:00';
- $page->AllowEmbargoedEditing = false;
- $page->write();
-
- $this->assertFalse($page->getIsUnPublishScheduled());
-
- $page->UnPublishOnDate = '2016-02-01 00:00:00';
- DBDatetime::set_mock_now('2016-01-16 00:00:00');
- $this->assertTrue($page->getIsUnPublishScheduled());
-
- DBDatetime::set_mock_now('2016-02-16 00:00:00');
- $this->assertFalse($page->getIsUnPublishScheduled());
- }
-
- /**
- * Tests that status flags (badges) are added properly for a page
- */
- public function testStatusFlags()
- {
- $page = SiteTree::create();
- $page->Title = 'stuff';
- DBDatetime::set_mock_now('2016-01-16 00:00:00');
-
- $flags = $page->getStatusFlags(false);
- $this->assertNotContains('embargo_expiry', array_keys($flags ?? []));
- $this->assertNotContains('embargo', array_keys($flags ?? []));
- $this->assertNotContains('expiry', array_keys($flags ?? []));
-
- $page->PublishOnDate = '2016-02-01 00:00:00';
- $page->UnPublishOnDate = null;
- $flags = $page->getStatusFlags(false);
- $this->assertNotContains('embargo_expiry', array_keys($flags ?? []));
- $this->assertContains('embargo', array_keys($flags ?? []));
- $this->assertNotContains('expiry', array_keys($flags ?? []));
-
- $page->PublishOnDate = null;
- $page->UnPublishOnDate = '2016-02-01 00:00:00';
- $flags = $page->getStatusFlags(false);
- $this->assertNotContains('embargo_expiry', array_keys($flags ?? []));
- $this->assertNotContains('embargo', array_keys($flags ?? []));
- $this->assertContains('expiry', array_keys($flags ?? []));
-
- $page->PublishOnDate = '2016-02-01 00:00:00';
- $page->UnPublishOnDate = '2016-02-08 00:00:00';
- $flags = $page->getStatusFlags(false);
- $this->assertContains('embargo_expiry', array_keys($flags ?? []));
- $this->assertNotContains('embargo', array_keys($flags ?? []));
- $this->assertNotContains('expiry', array_keys($flags ?? []));
- }
-
- /**
- * Test workflow definition "Can disable edits during embargo"
- * Make sure page cannot be edited when an embargo is in place
- */
- public function testCanEditConfig()
- {
- $this->logOut();
-
- $page = SiteTree::create();
- $page->Title = 'My page';
- $page->PublishOnDate = '2010-01-01 00:00:00';
- $page->write();
-
- $memberID = $this->logInWithPermission('SITETREE_EDIT_ALL');
- $this->assertTrue($page->canEdit(), 'Can edit page without embargo and no permission');
-
- $page->PublishOnDate = '2020-01-01 00:00:00';
- $page->AllowEmbargoedEditing = false;
- $page->write();
- $this->assertFalse($page->canEdit(), 'Cannot edit page with embargo and no permission');
-
- $this->logOut();
- $memberID = $this->logInWithPermission('ADMIN');
- $this->assertTrue($page->canEdit(), 'Can edit page with embargo as Admin');
-
- $this->logOut();
- $memberID = $this->logInWithPermission(array('SITETREE_EDIT_ALL', 'EDIT_EMBARGOED_WORKFLOW'));
- $this->assertTrue($page->canEdit(), 'Can edit page with embargo and permission');
-
- $page->PublishOnDate = '2010-01-01 00:00:00';
- $page->write();
- $this->assertTrue($page->canEdit(), 'Can edit page without embargo and permission');
- }
-
- protected function createDefinition()
- {
- $definition = new WorkflowDefinition();
- $definition->Title = 'Dummy Workflow Definition';
- $definition->write();
-
- $stepOne = new WorkflowAction();
- $stepOne->Title = 'Step One';
- $stepOne->WorkflowDefID = $definition->ID;
- $stepOne->write();
-
- $stepTwo = new WorkflowAction();
- $stepTwo->Title = 'Step Two';
- $stepTwo->WorkflowDefID = $definition->ID;
- $stepTwo->write();
-
- $transitionOne = new WorkflowTransition();
- $transitionOne->Title = 'Step One T1';
- $transitionOne->ActionID = $stepOne->ID;
- $transitionOne->NextActionID = $stepTwo->ID;
- $transitionOne->write();
-
- return $definition;
- }
-
- /**
- * Make sure that publish and unpublish dates are not carried over to the duplicates.
- */
- public function testDuplicateRemoveEmbargoExpiry()
- {
- $page = $this->objFromFixture(SiteTree::class, 'futureEmbargoExpiry');
-
- // fake publish jobs
+ /** @var SiteTree|EmbargoExpiryExtension $page */
$page = $this->finishWorkflow($page);
- $dupe = $page->duplicate();
- $this->assertNotNull($page->PublishOnDate, 'Not blank publish on date');
- $this->assertNotNull($page->UnPublishOnDate, 'Not blank unpublish on date');
- $this->assertNotEquals($page->PublishJobID, 0, 'Publish job ID still set');
- $this->assertNotEquals($page->UnPublishJobID, 0, 'Unpublish job ID still set');
- $this->assertNull($dupe->PublishOnDate, 'Blank publish on date');
- $this->assertNull($dupe->UnPublishOnDate, 'Blank unpublish on date');
- $this->assertEquals($dupe->PublishJobID, 0, 'Publish job ID unset');
- $this->assertEquals($dupe->UnPublishJobID, 0, 'Unpublish job ID unset');
+ // Check that the Jobs have been created, and that the object fields were correctly updated.
+ $this->assertNull($page->DesiredPublishDate);
+ $this->assertNull($page->DesiredUnPublishDate);
+ $this->assertNull($page->PublishOnDate);
+ $this->assertNotNull($page->UnPublishOnDate);
+ $this->assertEquals(0, $page->PublishJobID);
+ $this->assertTrue($page->UnPublishJob()->exists());
+
+ // This record should not yet be published.
+ $this->assertFalse($page->isPublished());
}
}
diff --git a/tests/php/WorkflowEmbargoExpiryTest.yml b/tests/php/WorkflowEmbargoExpiryTest.yml
new file mode 100644
index 00000000..08ac3611
--- /dev/null
+++ b/tests/php/WorkflowEmbargoExpiryTest.yml
@@ -0,0 +1,29 @@
+Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition:
+ requestPublication:
+ Title: 'Request Publish'
+ approvePublication:
+ Title: 'Approve Publish'
+
+Symbiote\AdvancedWorkflow\Actions\SimpleApprovalWorkflowAction:
+ requestPublication:
+ Title: 'Approve'
+ WorkflowDefID: =>Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition.requestPublication
+
+Symbiote\AdvancedWorkflow\Actions\PublishItemWorkflowAction:
+ approvePublication:
+ Title: 'Publish'
+ WorkflowDefID: =>Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition.approvePublication
+
+SilverStripe\CMS\Model\SiteTree:
+ emptyEmbargoExpiry:
+ Title: 'Empty embargo and expiry'
+ WorkflowDefinitionID: =>Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition.requestPublication
+ processEmbargoExpiry:
+ Title: 'Process embargo and expiry'
+ WorkflowDefinitionID: =>Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition.requestPublication
+ processEmbargo:
+ Title: 'Process embargo'
+ WorkflowDefinitionID: =>Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition.requestPublication
+ processExpiry:
+ Title: 'Process expiry'
+ WorkflowDefinitionID: =>Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition.requestPublication