Completed
Push — master ( c0fbe9...e7535a )
by Robbie
13s
created

code/model/DMSDocumentSet.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * A document set is attached to Pages, and contains many DMSDocuments
4
 *
5
 * @property Varchar Title
6
 * @property  Text KeyValuePairs
7
 * @property  Enum SortBy
8
 * @property Enum SortByDirection
9
 */
10
class DMSDocumentSet extends DataObject
11
{
12
    private static $db = array(
13
        'Title' => 'Varchar(255)',
14
        'KeyValuePairs' => 'Text',
15
        'SortBy' => "Enum('LastEdited,Created,Title')')",
16
        'SortByDirection' => "Enum('DESC,ASC')')",
17
    );
18
19
    private static $has_one = array(
20
        'Page' => 'SiteTree',
21
    );
22
23
    private static $many_many = array(
24
        'Documents' => 'DMSDocument',
25
    );
26
27
    private static $many_many_extraFields = array(
28
        'Documents' => array(
29
            // Flag indicating if a document was added directly to a set - in which case it is set - or added
30
            // via the query-builder.
31
            'ManuallyAdded' => 'Boolean(1)',
32
            'DocumentSort' => 'Int'
33
        ),
34
    );
35
36
    private static $summary_fields = array(
37
        'Title' => 'Title',
38
        'Documents.Count' => 'No. Documents'
39
    );
40
41
    /**
42
     * Retrieve a list of the documents in this set. An extension hook is provided before the result is returned.
43
     *
44
     * You can attach an extension to this event:
45
     *
46
     * <code>
47
     * public function updateDocuments($document)
48
     * {
49
     *     // do something
50
     * }
51
     * </code>
52
     *
53
     * @return DataList|null
54
     */
55
    public function getDocuments()
56
    {
57
        $documents = $this->Documents();
58
        $this->extend('updateDocuments', $documents);
59
        return $documents;
60
    }
61
62
    /**
63
     * Put the "documents" list into the main tab instead of its own tab, and replace the default "Add Document" button
64
     * with a customised button for DMS documents
65
     *
66
     * @return FieldList
67
     */
68
    public function getCMSFields()
69
    {
70
        // PHP 5.3 only
71
        $self = $this;
72
        $this->beforeUpdateCMSFields(function (FieldList $fields) use ($self) {
73
            $fields->removeFieldsFromTab(
74
                'Root.Main',
75
                array('KeyValuePairs', 'SortBy', 'SortByDirection')
76
            );
77
            // Don't put the GridField for documents in until the set has been created
78
            if (!$self->isInDB()) {
79
                $fields->addFieldToTab(
80
                    'Root.Main',
81
                    LiteralField::create(
82
                        'GridFieldNotice',
83
                        '<p class="message warning">' . _t(
84
                            'DMSDocumentSet.GRIDFIELD_NOTICE',
85
                            'Managing documents will be available once you have created this document set.'
86
                        ) . '</p>'
87
                    ),
88
                    'Title'
89
                );
90
            } else {
91
                $fields->removeByName('DocumentSetSort');
92
                // Document listing
93
                $gridFieldConfig = GridFieldConfig::create()
94
                    ->addComponents(
95
                        new GridFieldButtonRow('before'),
96
                        new GridFieldToolbarHeader(),
97
                        new GridFieldFilterHeader(),
98
                        new GridFieldSortableHeader(),
99
                        new GridFieldDataColumns(),
100
                        new DMSGridFieldEditButton(),
101
                        // Special delete dialog to handle custom behaviour of unlinking and deleting
102
                        new GridFieldDeleteAction(true),
103
                        new GridFieldDetailForm()
104
                    );
105
106
                if (class_exists('GridFieldPaginatorWithShowAll')) {
107
                    $paginatorComponent = new GridFieldPaginatorWithShowAll(15);
108
                } else {
109
                    $paginatorComponent = new GridFieldPaginator(15);
110
                }
111
                $gridFieldConfig->addComponent($paginatorComponent);
112
113
                if (class_exists('GridFieldSortableRows')) {
114
                    $gridFieldConfig->addComponent(new GridFieldSortableRows('DocumentSort'));
115
                } elseif (class_exists('GridFieldOrderableRows')) {
116
                    $gridFieldConfig->addComponent(new GridFieldOrderableRows('DocumentSort'));
117
                }
118
119
                // Don't show which page this is if we're already editing within a page context
120 View Code Duplication
                if (Controller::curr() instanceof CMSPageEditController) {
121
                    $fields->removeByName('PageID');
122
                } else {
123
                    $fields->fieldByName('Root.Main.PageID')->setTitle(_t('DMSDocumentSet.SHOWONPAGE', 'Show on page'));
124
                }
125
126
                // Don't show which page this is if we're already editing within a page context
127 View Code Duplication
                if (Controller::curr() instanceof CMSPageEditController) {
128
                    $fields->removeByName('PageID');
129
                } else {
130
                    $fields->fieldByName('Root.Main.PageID')->setTitle(_t('DMSDocumentSet.SHOWONPAGE', 'Show on page'));
131
                }
132
133
                $gridFieldConfig->getComponentByType('GridFieldDataColumns')
134
                    ->setDisplayFields($self->getDocumentDisplayFields())
135
                    ->setFieldCasting(array('LastEdited' => 'Datetime->Ago'))
136
                    ->setFieldFormatting(
137
                        array(
138
                            'FilenameWithoutID' => '<a target=\'_blank\' class=\'file-url\''
139
                                . ' href=\'$Link\'>$FilenameWithoutID</a>',
140
                            'ManuallyAdded' => function ($value) {
141
                                if ($value) {
142
                                    return _t('DMSDocumentSet.MANUAL', 'Manually');
143
                                }
144
                                return _t('DMSDocumentSet.QUERYBUILDER', 'Query Builder');
145
                            }
146
                        )
147
                    );
148
149
                // Override delete functionality with this class
150
                $gridFieldConfig->getComponentByType('GridFieldDetailForm')
151
                    ->setItemRequestClass('DMSGridFieldDetailForm_ItemRequest');
152
                $gridField = GridField::create(
153
                    'Documents',
154
                    false,
155
                    $self->Documents(),
156
                    $gridFieldConfig
157
                );
158
                $gridField->setModelClass('DMSDocument');
159
                $gridField->addExtraClass('documents');
160
161
                $gridFieldConfig->addComponent(
162
                    $addNewButton = new DMSGridFieldAddNewButton('buttons-before-left'),
163
                    'GridFieldExportButton'
164
                );
165
                $addNewButton->setDocumentSetId($self->ID);
166
167
                $fields->removeByName('Documents');
168
                $fields->addFieldsToTab(
169
                    'Root.Main',
170
                    array(
171
                        $gridField,
172
                        HiddenField::create('DMSShortcodeHandlerKey', false, DMS::inst()->getShortcodeHandlerKey())
173
                    )
174
                );
175
                $self->addQueryFields($fields);
176
            }
177
        });
178
        $this->addRequirements();
179
        return parent::getCMSFields();
180
    }
181
182
    /**
183
     * Add required CSS and Javascript requirements for managing documents
184
     *
185
     * @return $this
186
     */
187
    protected function addRequirements()
188
    {
189
        // Javascript to customize the grid field for the DMS document (overriding entwine
190
        // in FRAMEWORK_DIR.'/javascript/GridField.js'
191
        Requirements::javascript(DMS_DIR . '/javascript/DMSGridField.js');
192
        Requirements::css(DMS_DIR . '/dist/css/dmsbundle.css');
193
194
        // Javascript for the link editor pop-up in TinyMCE
195
        Requirements::javascript(DMS_DIR . '/javascript/DocumentHtmlEditorFieldToolbar.js');
196
197
        return $this;
198
    }
199
200
    /**
201
     * Adds the query fields to build the document logic to the DMSDocumentSet.
202
     *
203
     * @param FieldList $fields
204
     */
205
    public function addQueryFields($fields)
206
    {
207
        /** @var DMSDocument $doc */
208
        $doc = singleton('DMSDocument');
209
        /** @var FormField $field */
210
        $dmsDocFields = $doc->scaffoldSearchFields(array('fieldClasses' => true));
211
        $membersMap = Member::get()->map('ID', 'Name')->toArray();
212
        asort($membersMap);
213
214
        foreach ($dmsDocFields as $field) {
215
            if ($field instanceof ListboxField) {
216
                $map = ($field->getName() === 'Tags__ID') ? $doc->getAllTagsMap() : $membersMap;
217
                $field->setMultiple(true)->setSource($map);
218
219
                if ($field->getName() === 'Tags__ID') {
220
                    $field->setRightTitle(
221
                        _t(
222
                            'DMSDocumentSet.TAGS_RIGHT_TITLE',
223
                            'Tags can be set in the taxonomy area, and can be assigned when editing a document.'
224
                        )
225
                    );
226
                }
227
            }
228
        }
229
        $keyValPairs = DMSJsonField::create('KeyValuePairs', $dmsDocFields->toArray());
230
231
        // Now lastly add the sort fields
232
        $sortedBy = FieldGroup::create('SortedBy', array(
233
            DropdownField::create('SortBy', '', array(
234
                'LastEdited'  => 'Last changed',
235
                'Created'     => 'Created',
236
                'Title'       => 'Document title',
237
            ), 'LastEdited'),
238
            DropdownField::create(
239
                'SortByDirection',
240
                '',
241
                array(
242
                    'DESC' => _t('DMSDocumentSet.DIRECTION_DESCENDING', 'Descending'),
243
                    'ASC' => _t('DMSDocumentSet.DIRECTION_ASCENDING', 'Ascending')
244
                ),
245
                'DESC'
246
            ),
247
        ));
248
249
        $sortedBy->setTitle(_t('DMSDocumentSet.SORTED_BY', 'Sort the document set by:'));
250
        $fields->addFieldsToTab(
251
            'Root.QueryBuilder',
252
            array(
253
                LiteralField::create(
254
                    'GridFieldNotice',
255
                    '<p class="message warning">' . _t(
256
                        'DMSDocumentSet.QUERY_BUILDER_NOTICE',
257
                        'The query builder provides the ability to add documents to a document set based on the ' .
258
                        'filters below. Please note that the set will be built using this criteria when you save the ' .
259
                        'form. This set will not be dynamically updated (see the documentation for more information).'
260
                    ) . '</p>'
261
                ),
262
                $keyValPairs,
263
                $sortedBy
264
            )
265
        );
266
    }
267
268
    public function onBeforeWrite()
269
    {
270
        parent::onBeforeWrite();
271
272
        $this->saveLinkedDocuments();
273
    }
274
275
    /**
276
     * Retrieve a list of the documents in this set. An extension hook is provided before the result is returned.
277
     */
278
    public function saveLinkedDocuments()
279
    {
280
        if (empty($this->KeyValuePairs) || !$this->isChanged('KeyValuePairs')) {
281
            return;
282
        }
283
284
        $keyValuesPair = Convert::json2array($this->KeyValuePairs);
285
286
        /** @var DMSDocument $dmsDoc */
287
        $dmsDoc = singleton('DMSDocument');
288
        $context = $dmsDoc->getDefaultSearchContext();
289
290
        $sortBy = $this->SortBy ? $this->SortBy : 'LastEdited';
291
        $sortByDirection = $this->SortByDirection ? $this->SortByDirection : 'DESC';
292
        $sortedBy = sprintf('%s %s', $sortBy, $sortByDirection);
293
294
        /** @var DataList $documents */
295
        $documents = $context->getResults($keyValuesPair, $sortedBy);
296
        $documents = $this->addEmbargoConditions($documents);
297
        $documents = $this->addQueryBuilderSearchResults($documents);
0 ignored issues
show
$documents is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
298
    }
299
300
    /**
301
     * Add embargo date conditions to a search query
302
     *
303
     * @param  DataList $documents
304
     * @return DataList
305
     */
306
    protected function addEmbargoConditions(DataList $documents)
307
    {
308
        $now = SS_Datetime::now()->Rfc2822();
309
310
        return $documents->where(
311
            "\"EmbargoedIndefinitely\" = 0 AND "
312
            . " \"EmbargoedUntilPublished\" = 0 AND "
313
            . "(\"EmbargoedUntilDate\" IS NULL OR "
314
            . "(\"EmbargoedUntilDate\" IS NOT NULL AND '{$now}' >= \"EmbargoedUntilDate\")) AND "
315
            . "\"ExpireAtDate\" IS NULL OR (\"ExpireAtDate\" IS NOT NULL AND '{$now}' < \"ExpireAtDate\")"
316
        );
317
    }
318
319
    /**
320
     * Remove all ManuallyAdded = 0 original results and add in the new documents returned by the search context
321
     *
322
     * @param  DataList $documents
323
     * @return DataList
324
     */
325
    protected function addQueryBuilderSearchResults(DataList $documents)
326
    {
327
        /** @var ManyManyList $originals Documents that belong to just this set. */
328
        $originals = $this->Documents();
329
        $originals->removeByFilter('"ManuallyAdded" = 0');
330
331
        foreach ($documents as $document) {
332
            $originals->add($document, array('ManuallyAdded' => 0));
333
        }
334
335
        return $originals;
336
    }
337
338
    /**
339
     * Customise the display fields for the documents GridField
340
     *
341
     * @return array
342
     */
343
    public function getDocumentDisplayFields()
344
    {
345
        return array_merge(
346
            (array) DMSDocument::create()->config()->get('display_fields'),
347
            array('ManuallyAdded' => _t('DMSDocumentSet.ADDEDMETHOD', 'Added'))
348
        );
349
    }
350
351
    protected function validate()
352
    {
353
        $result = parent::validate();
354
355
        if (!$this->getTitle()) {
356
            $result->error(_t('DMSDocumentSet.VALIDATION_NO_TITLE', '\'Title\' is required.'));
357
        }
358
        return $result;
359
    }
360
361 View Code Duplication
    public function canView($member = null)
362
    {
363
        $extended = $this->extendedCan(__FUNCTION__, $member);
364
        if ($extended !== null) {
365
            return $extended;
366
        }
367
        return $this->getGlobalPermission($member);
368
    }
369
370 View Code Duplication
    public function canCreate($member = null)
371
    {
372
        $extended = $this->extendedCan(__FUNCTION__, $member);
373
        if ($extended !== null) {
374
            return $extended;
375
        }
376
        return $this->getGlobalPermission($member);
377
    }
378
379 View Code Duplication
    public function canEdit($member = null)
380
    {
381
        $extended = $this->extendedCan(__FUNCTION__, $member);
382
        if ($extended !== null) {
383
            return $extended;
384
        }
385
        return $this->getGlobalPermission($member);
386
    }
387
388 View Code Duplication
    public function canDelete($member = null)
389
    {
390
        $extended = $this->extendedCan(__FUNCTION__, $member);
391
        if ($extended !== null) {
392
            return $extended;
393
        }
394
        return $this->getGlobalPermission($member);
395
    }
396
397
    /**
398
     * Checks if a then given (or logged in) member is either an ADMIN, SITETREE_EDIT_ALL or has access
399
     * to the DMSDocumentAdmin module, in which case permissions is granted.
400
     *
401
     * @param Member $member
402
     * @return bool
403
     */
404
    public function getGlobalPermission(Member $member = null)
405
    {
406 View Code Duplication
        if (!$member || !(is_a($member, 'Member')) || is_numeric($member)) {
407
            $member = Member::currentUser();
408
        }
409
410
        $result = ($member &&
411
            Permission::checkMember(
412
                $member,
413
                array('ADMIN', 'SITETREE_EDIT_ALL', 'CMS_ACCESS_DMSDocumentAdmin')
414
            )
415
        );
416
417
        return (bool) $result;
418
    }
419
}
420