GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

WorkflowEmbargoExpiryExtension   F
last analyzed

Complexity

Total Complexity 74

Size/Duplication

Total Lines 546
Duplicated Lines 9.89 %

Coupling/Cohesion

Components 1
Dependencies 16

Importance

Changes 0
Metric Value
wmc 74
lcom 1
cbo 16
dl 54
loc 546
rs 2.48
c 0
b 0
f 0

20 Methods

Rating   Name   Duplication   Size   Complexity  
B updateCMSFields() 0 83 2
A clearPublishJob() 0 8 3
A clearUnPublishJob() 0 9 3
A ensurePublishJob() 17 17 6
A ensureUnPublishJob() 17 17 6
A onBeforeDuplicate() 0 9 1
C onBeforeWrite() 0 72 17
B updateStatusFlags() 0 40 7
A getIntroMessageParts() 0 24 2
A getIntroMessage() 0 7 1
A getCMSValidator() 0 6 1
B extendedRequiredFieldsEmbargoExpiry() 0 35 8
A getUserDate() 0 6 1
A setIsWorkflowInEffect() 0 6 2
A getIsWorkflowInEffect() 0 4 1
A getIsPublishScheduled() 10 10 2
A getIsUnPublishScheduled() 10 10 2
B canEdit() 0 15 7
A setWorkflowService() 0 5 1
A getWorkflowService() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like WorkflowEmbargoExpiryExtension often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WorkflowEmbargoExpiryExtension, and based on these observations, apply Extract Interface, too.

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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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)
0 ignored issues
show
Unused Code introduced by
The parameter $original is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $doWrite is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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