1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Symbiote\AdvancedWorkflow\Extensions; |
4
|
|
|
|
5
|
|
|
use SilverStripe\Control\Controller; |
6
|
|
|
use SilverStripe\Core\Injector\Injector; |
7
|
|
|
use SilverStripe\Core\Manifest\ModuleLoader; |
8
|
|
|
use SilverStripe\Forms\FieldList; |
9
|
|
|
use SilverStripe\Forms\DatetimeField; |
10
|
|
|
use SilverStripe\Forms\HeaderField; |
11
|
|
|
use SilverStripe\Forms\LiteralField; |
12
|
|
|
use SilverStripe\ORM\ArrayList; |
13
|
|
|
use SilverStripe\ORM\DataExtension; |
14
|
|
|
use SilverStripe\ORM\DataQuery; |
15
|
|
|
use SilverStripe\ORM\FieldType\DBDatetime; |
16
|
|
|
use SilverStripe\ORM\Queries\SQLSelect; |
17
|
|
|
use SilverStripe\Security\Member; |
18
|
|
|
use SilverStripe\Security\Permission; |
19
|
|
|
use SilverStripe\View\Requirements; |
20
|
|
|
use SilverStripe\Versioned\Versioned; |
21
|
|
|
use Symbiote\AdvancedWorkflow\Forms\AWRequiredFields; |
22
|
|
|
use Symbiote\AdvancedWorkflow\Jobs\WorkflowPublishTargetJob; |
23
|
|
|
use Symbiote\AdvancedWorkflow\Services\WorkflowService; |
24
|
|
|
use Symbiote\QueuedJobs\DataObjects\QueuedJobDescriptor; |
25
|
|
|
use Symbiote\QueuedJobs\Services\QueuedJobService; |
26
|
|
|
|
27
|
|
|
// Queued jobs descriptor is required for this extension |
28
|
|
|
if (!class_exists(QueuedJobDescriptor::class)) { |
29
|
|
|
return; |
30
|
|
|
} |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Adds embargo period and expiry dates to content items |
34
|
|
|
* |
35
|
|
|
* @author [email protected] |
36
|
|
|
* @license BSD License http://silverstripe.org/bsd-license/ |
37
|
|
|
*/ |
38
|
|
|
class WorkflowEmbargoExpiryExtension extends DataExtension |
39
|
|
|
{ |
40
|
|
|
private static $db = array( |
41
|
|
|
'DesiredPublishDate' => 'DBDatetime', |
42
|
|
|
'DesiredUnPublishDate' => 'DBDatetime', |
43
|
|
|
'PublishOnDate' => 'DBDatetime', |
44
|
|
|
'UnPublishOnDate' => 'DBDatetime', |
45
|
|
|
'AllowEmbargoedEditing' => 'Boolean', |
46
|
|
|
); |
47
|
|
|
|
48
|
|
|
private static $has_one = array( |
49
|
|
|
'PublishJob' => QueuedJobDescriptor::class, |
50
|
|
|
'UnPublishJob' => QueuedJobDescriptor::class, |
51
|
|
|
); |
52
|
|
|
|
53
|
|
|
private static $dependencies = array( |
54
|
|
|
'workflowService' => '%$' . WorkflowService::class, |
55
|
|
|
); |
56
|
|
|
|
57
|
|
|
private static $defaults = array( |
58
|
|
|
'AllowEmbargoedEditing' => true |
59
|
|
|
); |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @deprecated 5.2.0:6.0.0 This setting does nothing and will be removed in in 6.0 |
63
|
|
|
* @var bool |
64
|
|
|
*/ |
65
|
|
|
public static $showTimePicker = true; |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* @var WorkflowService |
69
|
|
|
*/ |
70
|
|
|
protected $workflowService; |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Is a workflow in effect? |
74
|
|
|
* |
75
|
|
|
* @var bool |
76
|
|
|
*/ |
77
|
|
|
public $isWorkflowInEffect = false; |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* A basic extended validation routine method return format |
81
|
|
|
* |
82
|
|
|
* @var array |
83
|
|
|
*/ |
84
|
|
|
public static $extendedMethodReturn = array( |
85
|
|
|
'fieldName' => null, |
86
|
|
|
'fieldField' => null, |
87
|
|
|
'fieldMsg' => null, |
88
|
|
|
'fieldValid' => true, |
89
|
|
|
); |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* @param FieldList $fields |
93
|
|
|
*/ |
94
|
|
|
public function updateCMSFields(FieldList $fields) |
95
|
|
|
{ |
96
|
|
|
// requirements |
97
|
|
|
// ------------ |
98
|
|
|
$module = 'symbiote/silverstripe-advancedworkflow'; |
99
|
|
|
Requirements::add_i18n_javascript($module . ':client/lang'); |
100
|
|
|
Requirements::css($module . ':client/dist/styles/advancedworkflow.css'); |
101
|
|
|
Requirements::javascript($module . ':client/dist/js/advancedworkflow.js'); |
102
|
|
|
|
103
|
|
|
// Fields |
104
|
|
|
// ------ |
105
|
|
|
|
106
|
|
|
// we never show these explicitly in admin |
107
|
|
|
$fields->removeByName('PublishJobID'); |
108
|
|
|
$fields->removeByName('UnPublishJobID'); |
109
|
|
|
|
110
|
|
|
$this->setIsWorkflowInEffect(); |
111
|
|
|
|
112
|
|
|
$fields->findOrMakeTab( |
113
|
|
|
'Root.PublishingSchedule', |
114
|
|
|
_t('WorkflowEmbargoExpiryExtension.TabTitle', 'Publishing Schedule') |
115
|
|
|
); |
116
|
|
|
if ($this->getIsWorkflowInEffect()) { |
117
|
|
|
// add fields we want in this context |
118
|
|
|
$fields->addFieldsToTab('Root.PublishingSchedule', array( |
119
|
|
|
HeaderField::create( |
120
|
|
|
'PublishDateHeader', |
121
|
|
|
_t('WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE_H3', 'Expiry and Embargo'), |
122
|
|
|
3 |
123
|
|
|
), |
124
|
|
|
LiteralField::create('PublishDateIntro', $this->getIntroMessage('PublishDateIntro')), |
125
|
|
|
$dt = DatetimeField::create( |
126
|
|
|
'DesiredPublishDate', |
127
|
|
|
_t('WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE', 'Requested publish date') |
128
|
|
|
)->setRightTitle( |
129
|
|
|
_t( |
130
|
|
|
'WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE_RIGHT_TITLE', |
131
|
|
|
'To request this page to be <strong>published immediately</strong> ' |
132
|
|
|
. 'leave the date and time fields blank' |
133
|
|
|
) |
134
|
|
|
), |
135
|
|
|
$ut = DatetimeField::create( |
136
|
|
|
'DesiredUnPublishDate', |
137
|
|
|
_t('WorkflowEmbargoExpiryExtension.REQUESTED_UNPUBLISH_DATE', 'Requested un-publish date') |
138
|
|
|
)->setRightTitle( |
139
|
|
|
_t( |
140
|
|
|
'WorkflowEmbargoExpiryExtension.REQUESTED_UNPUBLISH_DATE_RIGHT_TITLE', |
141
|
|
|
'To request this page to <strong>never expire</strong> leave the date and time fields blank' |
142
|
|
|
) |
143
|
|
|
), |
144
|
|
|
DatetimeField::create( |
145
|
|
|
'PublishOnDate', |
146
|
|
|
_t('WorkflowEmbargoExpiryExtension.PUBLISH_ON', 'Scheduled publish date') |
147
|
|
|
)->setDisabled(true), |
148
|
|
|
DatetimeField::create( |
149
|
|
|
'UnPublishOnDate', |
150
|
|
|
_t('WorkflowEmbargoExpiryExtension.UNPUBLISH_ON', 'Scheduled un-publish date') |
151
|
|
|
)->setDisabled(true) |
152
|
|
|
)); |
153
|
|
|
} else { |
154
|
|
|
// remove fields that have been automatically added that we don't want |
155
|
|
|
$fields->removeByName('DesiredPublishDate'); |
156
|
|
|
$fields->removeByName('DesiredUnPublishDate'); |
157
|
|
|
|
158
|
|
|
// add fields we want in this context |
159
|
|
|
$fields->addFieldsToTab('Root.PublishingSchedule', array( |
160
|
|
|
HeaderField::create( |
161
|
|
|
'PublishDateHeader', |
162
|
|
|
_t('WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE_H3', 'Expiry and Embargo'), |
163
|
|
|
3 |
164
|
|
|
), |
165
|
|
|
LiteralField::create('PublishDateIntro', $this->getIntroMessage('PublishDateIntro')), |
166
|
|
|
$dt = DatetimeField::create( |
167
|
|
|
'PublishOnDate', |
168
|
|
|
_t('WorkflowEmbargoExpiryExtension.PUBLISH_ON', 'Scheduled publish date') |
169
|
|
|
), |
170
|
|
|
$ut = DatetimeField::create( |
171
|
|
|
'UnPublishOnDate', |
172
|
|
|
_t('WorkflowEmbargoExpiryExtension.UNPUBLISH_ON', 'Scheduled un-publish date') |
173
|
|
|
), |
174
|
|
|
)); |
175
|
|
|
} |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
/** |
179
|
|
|
* Clears any existing publish job against this dataobject |
180
|
|
|
*/ |
181
|
|
|
public function clearPublishJob() |
182
|
|
|
{ |
183
|
|
|
$job = $this->owner->PublishJob(); |
184
|
|
|
if ($job && $job->exists()) { |
185
|
|
|
$job->delete(); |
186
|
|
|
} |
187
|
|
|
$this->owner->PublishJobID = 0; |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* Clears any existing unpublish job |
192
|
|
|
*/ |
193
|
|
|
public function clearUnPublishJob() |
194
|
|
|
{ |
195
|
|
|
// Cancel any in-progress unpublish job |
196
|
|
|
$job = $this->owner->UnPublishJob(); |
197
|
|
|
if ($job && $job->exists()) { |
198
|
|
|
$job->delete(); |
199
|
|
|
} |
200
|
|
|
$this->owner->UnPublishJobID = 0; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* Ensure the existence of a publish job at the specified time |
205
|
|
|
* |
206
|
|
|
* @param int $when Timestamp to start this job, or null to start immediately |
207
|
|
|
*/ |
208
|
|
View Code Duplication |
protected function ensurePublishJob($when) |
|
|
|
|
209
|
|
|
{ |
210
|
|
|
// Check if there is a prior job |
211
|
|
|
if ($this->owner->PublishJobID) { |
212
|
|
|
$job = $this->owner->PublishJob(); |
213
|
|
|
// Use timestamp for sake of comparison. |
214
|
|
|
if ($job && $job->exists() && DBDatetime::create()->setValue($job->StartAfter)->getTimestamp() == $when) { |
215
|
|
|
return; |
216
|
|
|
} |
217
|
|
|
$this->clearPublishJob(); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
// Create a new job with the specified schedule |
221
|
|
|
$job = new WorkflowPublishTargetJob($this->owner, 'publish'); |
222
|
|
|
$this->owner->PublishJobID = Injector::inst()->get(QueuedJobService::class) |
223
|
|
|
->queueJob($job, $when ? date('Y-m-d H:i:s', $when) : null); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* Ensure the existence of an unpublish job at the specified time |
228
|
|
|
* |
229
|
|
|
* @param int $when Timestamp to start this job, or null to start immediately |
230
|
|
|
*/ |
231
|
|
View Code Duplication |
protected function ensureUnPublishJob($when) |
|
|
|
|
232
|
|
|
{ |
233
|
|
|
// Check if there is a prior job |
234
|
|
|
if ($this->owner->UnPublishJobID) { |
235
|
|
|
$job = $this->owner->UnPublishJob(); |
236
|
|
|
// Use timestamp for sake of comparison. |
237
|
|
|
if ($job && $job->exists() && DBDatetime::create()->setValue($job->StartAfter)->getTimestamp() == $when) { |
238
|
|
|
return; |
239
|
|
|
} |
240
|
|
|
$this->clearUnPublishJob(); |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
// Create a new job with the specified schedule |
244
|
|
|
$job = new WorkflowPublishTargetJob($this->owner, 'unpublish'); |
245
|
|
|
$this->owner->UnPublishJobID = Injector::inst()->get(QueuedJobService::class) |
246
|
|
|
->queueJob($job, $when ? date('Y-m-d H:i:s', $when) : null); |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
public function onBeforeDuplicate($original, $doWrite) |
|
|
|
|
250
|
|
|
{ |
251
|
|
|
$clone = $this->owner; |
252
|
|
|
|
253
|
|
|
$clone->PublishOnDate = null; |
254
|
|
|
$clone->UnPublishOnDate = null; |
255
|
|
|
$clone->clearPublishJob(); |
256
|
|
|
$clone->clearUnPublishJob(); |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* {@see PublishItemWorkflowAction} for approval of requested publish dates |
261
|
|
|
*/ |
262
|
|
|
public function onBeforeWrite() |
263
|
|
|
{ |
264
|
|
|
parent::onBeforeWrite(); |
265
|
|
|
|
266
|
|
|
// only operate on staging content for this extension; otherwise, you |
267
|
|
|
// need to publish the page to be able to set a 'future' publish... |
268
|
|
|
// while the same could be said for the unpublish, the 'publish' state |
269
|
|
|
// is the one that must be avoided so we allow setting the 'unpublish' |
270
|
|
|
// date for as-yet-not-published content. |
271
|
|
|
if (Versioned::get_stage() === Versioned::LIVE) { |
272
|
|
|
return; |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
/* |
276
|
|
|
* Without checking if there's actually a workflow in effect, simply saving |
277
|
|
|
* as draft, would clear the Scheduled Publish & Unpublish date fields, which we obviously |
278
|
|
|
* don't want during a workflow: These date fields should be treated as a content |
279
|
|
|
* change that also requires approval (where such an approval step exists). |
280
|
|
|
* |
281
|
|
|
* - Check to see if we've got 'desired' publish/unpublish date(s). |
282
|
|
|
* - Check if there's a workflow attached to this content |
283
|
|
|
* - Reset values if it's safe to do so |
284
|
|
|
*/ |
285
|
|
|
if (!$this->getIsWorkflowInEffect()) { |
286
|
|
|
$resetPublishOnDate = $this->owner->DesiredPublishDate && $this->owner->PublishOnDate; |
287
|
|
|
if ($resetPublishOnDate) { |
288
|
|
|
$this->owner->PublishOnDate = null; |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
$resetUnPublishOnDate = $this->owner->DesiredUnPublishDate && $this->owner->UnPublishOnDate; |
292
|
|
|
if ($resetUnPublishOnDate) { |
293
|
|
|
$this->owner->UnPublishOnDate = null; |
294
|
|
|
} |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
// Jobs can only be queued for records that already exist |
298
|
|
|
if (!$this->owner->ID) { |
299
|
|
|
return; |
300
|
|
|
} |
301
|
|
|
|
302
|
|
|
// Check requested dates of publish / unpublish, and whether the page should have already been unpublished |
303
|
|
|
$now = DBDatetime::now()->getTimestamp(); |
304
|
|
|
$publishTime = $this->owner->dbObject('PublishOnDate')->getTimestamp(); |
305
|
|
|
$unPublishTime = $this->owner->dbObject('UnPublishOnDate')->getTimestamp(); |
306
|
|
|
|
307
|
|
|
// We should have a publish job if: |
308
|
|
|
// if no unpublish or publish time, then the Workflow Publish Action will publish without a job |
309
|
|
|
if ((!$unPublishTime && $publishTime) // the unpublish date is not set |
310
|
|
|
|| ( |
311
|
|
|
// unpublish date has not passed |
312
|
|
|
$unPublishTime > $now |
313
|
|
|
// publish date not set or happens before unpublish date |
314
|
|
|
&& ($publishTime && ($publishTime < $unPublishTime)) |
315
|
|
|
) |
316
|
|
|
) { |
317
|
|
|
// Trigger time immediately if passed |
318
|
|
|
$this->ensurePublishJob($publishTime < $now ? null : $publishTime); |
319
|
|
|
} else { |
320
|
|
|
$this->clearPublishJob(); |
321
|
|
|
} |
322
|
|
|
|
323
|
|
|
// We should have an unpublish job if: |
324
|
|
|
if ($unPublishTime // we have an unpublish date |
325
|
|
|
&& |
326
|
|
|
$publishTime < $unPublishTime // publish date is before to unpublish date |
327
|
|
|
) { |
328
|
|
|
// Trigger time immediately if passed |
329
|
|
|
$this->ensureUnPublishJob($unPublishTime < $now ? null : $unPublishTime); |
330
|
|
|
} else { |
331
|
|
|
$this->clearUnPublishJob(); |
332
|
|
|
} |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
/** |
336
|
|
|
* Add badges to the site tree view to show that a page has been scheduled for publishing or unpublishing |
337
|
|
|
* |
338
|
|
|
* @param $flags |
339
|
|
|
*/ |
340
|
|
|
public function updateStatusFlags(&$flags) |
341
|
|
|
{ |
342
|
|
|
$embargo = $this->getIsPublishScheduled(); |
343
|
|
|
$expiry = $this->getIsUnPublishScheduled(); |
344
|
|
|
|
345
|
|
|
if ($embargo || $expiry) { |
346
|
|
|
unset($flags['addedtodraft'], $flags['modified']); |
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
if ($embargo && $expiry) { |
350
|
|
|
$flags['embargo_expiry'] = array( |
351
|
|
|
'text' => _t('WorkflowEmbargoExpiryExtension.BADGE_PUBLISH_UNPUBLISH', 'Embargo+Expiry'), |
352
|
|
|
'title' => sprintf( |
353
|
|
|
'%s: %s, %s: %s', |
354
|
|
|
_t('WorkflowEmbargoExpiryExtension.PUBLISH_ON', 'Scheduled publish date'), |
355
|
|
|
$this->owner->PublishOnDate, |
356
|
|
|
_t('WorkflowEmbargoExpiryExtension.UNPUBLISH_ON', 'Scheduled un-publish date'), |
357
|
|
|
$this->owner->UnPublishOnDate |
358
|
|
|
), |
359
|
|
|
); |
360
|
|
|
} elseif ($embargo) { |
361
|
|
|
$flags['embargo'] = array( |
362
|
|
|
'text' => _t('WorkflowEmbargoExpiryExtension.BADGE_PUBLISH', 'Embargo'), |
363
|
|
|
'title' => sprintf( |
364
|
|
|
'%s: %s', |
365
|
|
|
_t('WorkflowEmbargoExpiryExtension.PUBLISH_ON', 'Scheduled publish date'), |
366
|
|
|
$this->owner->PublishOnDate |
367
|
|
|
), |
368
|
|
|
); |
369
|
|
|
} elseif ($expiry) { |
370
|
|
|
$flags['expiry'] = array( |
371
|
|
|
'text' => _t('WorkflowEmbargoExpiryExtension.BADGE_UNPUBLISH', 'Expiry'), |
372
|
|
|
'title' => sprintf( |
373
|
|
|
'%s: %s', |
374
|
|
|
_t('WorkflowEmbargoExpiryExtension.UNPUBLISH_ON', 'Scheduled un-publish date'), |
375
|
|
|
$this->owner->UnPublishOnDate |
376
|
|
|
), |
377
|
|
|
); |
378
|
|
|
} |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
/* |
382
|
|
|
* Define an array of message-parts for use by {@link getIntroMessage()} |
383
|
|
|
* |
384
|
|
|
* @param string $key |
385
|
|
|
* @return array |
386
|
|
|
*/ |
387
|
|
|
public function getIntroMessageParts($key) |
388
|
|
|
{ |
389
|
|
|
$parts = array( |
390
|
|
|
'PublishDateIntro' => array( |
391
|
|
|
'INTRO'=>_t( |
392
|
|
|
'WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE_INTRO', |
393
|
|
|
'Enter a date and/or time to specify embargo and expiry dates.' |
394
|
|
|
), |
395
|
|
|
'BULLET_1'=>_t( |
396
|
|
|
'WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE_INTRO_BULLET_1', |
397
|
|
|
'These settings won\'t take effect until any approval actions are run' |
398
|
|
|
), |
399
|
|
|
'BULLET_2'=>_t( |
400
|
|
|
'WorkflowEmbargoExpiryExtension.REQUESTED_PUBLISH_DATE_INTRO_BULLET_2', |
401
|
|
|
'If an embargo is already set, adding a new one prior to that date\'s passing will overwrite it' |
402
|
|
|
) |
403
|
|
|
) |
404
|
|
|
); |
405
|
|
|
// If there's no effective workflow, no need for the first bullet-point |
406
|
|
|
if (!$this->getIsWorkflowInEffect()) { |
407
|
|
|
$parts['PublishDateIntro']['BULLET_1'] = false; |
408
|
|
|
} |
409
|
|
|
return $parts[$key]; |
410
|
|
|
} |
411
|
|
|
|
412
|
|
|
/* |
413
|
|
|
* Display some messages to the user, a little more complex that a simple one-liner |
414
|
|
|
* |
415
|
|
|
* @param string $key |
416
|
|
|
* @return string |
417
|
|
|
*/ |
418
|
|
|
public function getIntroMessage($key) |
419
|
|
|
{ |
420
|
|
|
$msg = $this->getIntroMessageParts($key); |
421
|
|
|
$curr = Controller::curr(); |
422
|
|
|
$msg = $curr->customise($msg)->renderWith('Includes/embargoIntro'); |
423
|
|
|
return $msg; |
424
|
|
|
} |
425
|
|
|
|
426
|
|
|
/* |
427
|
|
|
* Validate |
428
|
|
|
*/ |
429
|
|
|
public function getCMSValidator() |
430
|
|
|
{ |
431
|
|
|
$required = new AWRequiredFields(); |
432
|
|
|
$required->setCaller($this); |
433
|
|
|
return $required; |
434
|
|
|
} |
435
|
|
|
|
436
|
|
|
/** |
437
|
|
|
* This is called in the AWRequiredFields class, this validates whether an Embargo and Expiry are not equal and that |
438
|
|
|
* Embargo is before Expiry, returning the appropriate message when it fails. |
439
|
|
|
* |
440
|
|
|
* @param $data |
441
|
|
|
* @return array |
442
|
|
|
*/ |
443
|
|
|
public function extendedRequiredFieldsEmbargoExpiry($data) |
444
|
|
|
{ |
445
|
|
|
$response = array( |
446
|
|
|
'fieldName' => 'DesiredUnPublishDate[date]', |
447
|
|
|
'fieldField' => null, |
448
|
|
|
'fieldMsg' => null, |
449
|
|
|
'fieldValid' => true |
450
|
|
|
); |
451
|
|
|
|
452
|
|
|
if (isset($data['DesiredPublishDate'], $data['DesiredUnPublishDate'])) { |
453
|
|
|
$publish = DBDatetime::create()->setValue($data['DesiredPublishDate'])->getTimestamp(); |
454
|
|
|
$unpublish = DBDatetime::create()->setValue($data['DesiredUnPublishDate'])->getTimestamp(); |
455
|
|
|
|
456
|
|
|
// the times are the same |
457
|
|
|
if ($publish && $unpublish && $publish == $unpublish) { |
458
|
|
|
$response = array_merge($response, array( |
459
|
|
|
'fieldMsg' => _t( |
460
|
|
|
'WorkflowEmbargoExpiryExtension.INVALIDSAMEEMBARGOEXPIRY', |
461
|
|
|
'The publish date and unpublish date cannot be the same.' |
462
|
|
|
), |
463
|
|
|
'fieldValid' => false |
464
|
|
|
)); |
465
|
|
|
} elseif ($publish && $unpublish && $publish > $unpublish) { |
466
|
|
|
$response = array_merge($response, array( |
467
|
|
|
'fieldMsg' => _t( |
468
|
|
|
'WorkflowEmbargoExpiryExtension.INVALIDEXPIRY', |
469
|
|
|
'The unpublish date cannot be before the publish date.' |
470
|
|
|
), |
471
|
|
|
'fieldValid' => false |
472
|
|
|
)); |
473
|
|
|
} |
474
|
|
|
} |
475
|
|
|
|
476
|
|
|
return $response; |
477
|
|
|
} |
478
|
|
|
|
479
|
|
|
/** |
480
|
|
|
* Format a date according to member/user preferences |
481
|
|
|
* |
482
|
|
|
* @param string $date |
483
|
|
|
* @return string $date |
484
|
|
|
*/ |
485
|
|
|
public function getUserDate($date) |
486
|
|
|
{ |
487
|
|
|
$date = DBDatetime::create()->setValue($date); |
488
|
|
|
$member = Security::getCurrentUser(); |
489
|
|
|
return $date->FormatFromSettings($member); |
490
|
|
|
} |
491
|
|
|
|
492
|
|
|
/* |
493
|
|
|
* Sets property as boolean true|false if an effective workflow is found or not |
494
|
|
|
*/ |
495
|
|
|
public function setIsWorkflowInEffect() |
496
|
|
|
{ |
497
|
|
|
// if there is a workflow applied, we can't set the publishing date directly, only the 'desired' publishing date |
498
|
|
|
$effective = $this->getWorkflowService()->getDefinitionFor($this->owner); |
499
|
|
|
$this->isWorkflowInEffect = $effective ? true : false; |
500
|
|
|
} |
501
|
|
|
|
502
|
|
|
public function getIsWorkflowInEffect() |
503
|
|
|
{ |
504
|
|
|
return $this->isWorkflowInEffect; |
505
|
|
|
} |
506
|
|
|
|
507
|
|
|
/** |
508
|
|
|
* Returns whether a publishing date has been set and is after the current date |
509
|
|
|
* |
510
|
|
|
* @return bool |
511
|
|
|
*/ |
512
|
|
View Code Duplication |
public function getIsPublishScheduled() |
|
|
|
|
513
|
|
|
{ |
514
|
|
|
if (!$this->owner->PublishOnDate) { |
515
|
|
|
return false; |
516
|
|
|
} |
517
|
|
|
$now = DBDatetime::now()->getTimestamp(); |
518
|
|
|
$publish = $this->owner->dbObject('PublishOnDate')->getTimestamp(); |
519
|
|
|
|
520
|
|
|
return $now < $publish; |
521
|
|
|
} |
522
|
|
|
|
523
|
|
|
/** |
524
|
|
|
* Returns whether an unpublishing date has been set and is after the current date |
525
|
|
|
* |
526
|
|
|
* @return bool |
527
|
|
|
*/ |
528
|
|
View Code Duplication |
public function getIsUnPublishScheduled() |
|
|
|
|
529
|
|
|
{ |
530
|
|
|
if (!$this->owner->UnPublishOnDate) { |
531
|
|
|
return false; |
532
|
|
|
} |
533
|
|
|
$now = DBDatetime::now()->getTimestamp(); |
534
|
|
|
$unpublish = $this->owner->dbObject('UnPublishOnDate')->getTimestamp(); |
535
|
|
|
|
536
|
|
|
return $now < $unpublish; |
537
|
|
|
} |
538
|
|
|
|
539
|
|
|
/** |
540
|
|
|
* Add edit check for when publishing has been scheduled and if any workflow definitions want the item to be |
541
|
|
|
* disabled. |
542
|
|
|
* |
543
|
|
|
* @param Member $member |
544
|
|
|
* @return bool|null |
545
|
|
|
*/ |
546
|
|
|
public function canEdit($member) |
547
|
|
|
{ |
548
|
|
|
if (!Permission::check('EDIT_EMBARGOED_WORKFLOW') && // not given global/override permission to edit |
549
|
|
|
!$this->owner->AllowEmbargoedEditing) { // item flagged as not editable |
550
|
|
|
$publishTime = $this->owner->dbObject('PublishOnDate'); |
551
|
|
|
|
552
|
|
|
if ($publishTime && $publishTime->InFuture() || // when scheduled publish date is in the future |
553
|
|
|
// when there isn't a publish date, but a Job is in place (publish immediately, but queued jobs is |
554
|
|
|
// waiting) |
555
|
|
|
(!$publishTime && $this->owner->PublishJobID != 0) |
556
|
|
|
) { |
557
|
|
|
return false; |
558
|
|
|
} |
559
|
|
|
} |
560
|
|
|
} |
561
|
|
|
|
562
|
|
|
/** |
563
|
|
|
* Set the workflow service instance |
564
|
|
|
* |
565
|
|
|
* @param WorkflowService $workflowService |
566
|
|
|
* @return $this |
567
|
|
|
*/ |
568
|
|
|
public function setWorkflowService(WorkflowService $workflowService) |
569
|
|
|
{ |
570
|
|
|
$this->workflowService = $workflowService; |
571
|
|
|
return $this; |
572
|
|
|
} |
573
|
|
|
|
574
|
|
|
/** |
575
|
|
|
* Get the workflow service instance |
576
|
|
|
* |
577
|
|
|
* @return WorkflowService |
578
|
|
|
*/ |
579
|
|
|
public function getWorkflowService() |
580
|
|
|
{ |
581
|
|
|
return $this->workflowService; |
582
|
|
|
} |
583
|
|
|
} |
584
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.