PagesDueForReviewReport   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 210
Duplicated Lines 27.62 %

Coupling/Cohesion

Components 0
Dependencies 12

Importance

Changes 0
Metric Value
wmc 22
lcom 0
cbo 12
dl 58
loc 210
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A title() 0 4 1
B parameterFields() 0 35 1
C columns() 29 71 10
C sourceRecords() 29 80 10

How to fix   Duplicated Code   

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:

1
<?php
2
3
namespace SilverStripe\ContentReview\Reports;
4
5
use SilverStripe\CMS\Controllers\CMSPageEditController;
6
use SilverStripe\CMS\Model\SiteTree;
7
use SilverStripe\CMS\Model\VirtualPage;
8
use SilverStripe\ContentReview\Compatibility\ContentReviewCompatability;
9
use SilverStripe\ContentReview\Extensions\ContentReviewOwner;
10
use SilverStripe\Core\ClassInfo;
11
use SilverStripe\Core\Config\Config;
12
use SilverStripe\Core\Convert;
13
use SilverStripe\Forms\CheckboxField;
14
use SilverStripe\Forms\DateField;
15
use SilverStripe\Forms\FieldList;
16
use SilverStripe\i18n\i18n;
17
use SilverStripe\ORM\FieldType\DBDatetime;
18
use SilverStripe\Reports\Report;
19
use SilverStripe\Security\Security;
20
use SilverStripe\SiteConfig\SiteConfig;
21
use SilverStripe\Versioned\Versioned;
22
23
/**
24
 * Show all pages that need to be reviewed.
25
 */
26
class PagesDueForReviewReport extends Report
27
{
28
    /**
29
     * @return string
30
     */
31
    public function title()
32
    {
33
        return _t("PagesDueForReviewReport.TITLE", "Pages due for review");
34
    }
35
36
    /**
37
     * @return FieldList
38
     */
39
    public function parameterFields()
40
    {
41
        $filtersList = FieldList::create();
42
43
        $filtersList->push(
44
            DateField::create(
45
                "ReviewDateAfter",
46
                _t("PagesDueForReviewReport.REVIEWDATEAFTER", "Review date after or on")
47
            )
48
        );
49
50
        $filtersList->push(
51
            DateField::create(
52
                "ReviewDateBefore",
53
                _t("PagesDueForReviewReport.REVIEWDATEBEFORE", "Review date before or on"),
54
                date("d/m/Y", strtotime("midnight"))
55
            )
56
        );
57
58
        $filtersList->push(
59
            CheckboxField::create(
60
                "ShowVirtualPages",
61
                _t("PagesDueForReviewReport.SHOWVIRTUALPAGES", "Show Virtual Pages")
62
            )
63
        );
64
65
        $filtersList->push(
66
            CheckboxField::create(
67
                "OnlyMyPages",
68
                _t("PagesDueForReviewReport.ONLYMYPAGES", "Only Show pages assigned to me")
69
            )
70
        );
71
72
        return $filtersList;
73
    }
74
75
    /**
76
     * @return array
77
     */
78
    public function columns()
79
    {
80
        $linkBase = singleton(CMSPageEditController::class)->Link("show");
81
        $linkPath = parse_url($linkBase, PHP_URL_PATH);
82
        $linkQuery = parse_url($linkBase, PHP_URL_QUERY);
83
84
        $fields = array(
85
            "Title" => array(
86
                "title" => "Page name",
87
                "formatting" => "<a href='{$linkPath}/\$ID?{$linkQuery}' title='Edit page'>\$value</a>"
88
            ),
89
            "NextReviewDate" => array(
90
                "title" => "Review Date",
91
                "casting" => "Date->Full",
92
                "formatting" => function ($value, $item) {
93
                    if ($item->ContentReviewType == "Disabled") {
94
                        return "disabled";
95
                    }
96
                    if ($item->ContentReviewType == "Inherit") {
97
                        $setting = $item->getOptions();
98
                        if (!$setting) {
99
                            return "disabled";
100
                        }
101
                        return $item->obj("NextReviewDate")->Full();
102
                    }
103
                    return $value;
104
                }
105
            ),
106
            "OwnerNames" => array(
107
                "title" => "Owner"
108
            ),
109
            "LastEditedByName" => "Last edited by",
110
            "AbsoluteLink" => array(
111
                "title" => "URL",
112 View Code Duplication
                "formatting" => function ($value, $item) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
113
                    $liveLink = $item->AbsoluteLiveLink;
114
                    $stageLink = $item->AbsoluteLink();
115
116
                    return sprintf(
117
                        "%s <a href='%s'>%s</a>",
118
                        $stageLink,
119
                        $liveLink ? $liveLink : $stageLink . "?stage=Stage",
120
                        $liveLink ? "(live)" : "(draft)"
121
                    );
122
                }
123
            ),
124
            "ContentReviewType" => array(
125
                "title" => "Settings are",
126 View Code Duplication
                "formatting" => function ($value, $item) use ($linkPath, $linkQuery) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
127
                    if ($item->ContentReviewType == "Inherit") {
128
                        $options = $item->getOptions();
129
                        if ($options && $options instanceof SiteConfig) {
130
                            return "Inherited from <a href='admin/settings'>Settings</a>";
131
                        } elseif ($options) {
132
                            return sprintf(
133
                                "Inherited from <a href='%s/%d?%s'>%s</a>",
134
                                $linkPath,
135
                                $options->ID,
136
                                $linkQuery,
137
                                $options->Title
138
                            );
139
                        }
140
                    }
141
142
                    return $value;
143
                }
144
            ),
145
        );
146
147
        return $fields;
148
    }
149
150
    /**
151
     * @param array $params
152
     *
153
     * @return SS_List
154
     */
155
    public function sourceRecords($params = array())
156
    {
157
        Versioned::set_stage(Versioned::DRAFT);
158
159
        $records = SiteTree::get();
160
        $compatibility = ContentReviewCompatability::start();
161
162
        if (empty($params['ReviewDateBefore']) && empty($params['ReviewDateAfter'])) {
163
            // If there's no review dates set, default to all pages due for review now
164
            $records = $records->where(
165
                sprintf(
166
                    '"NextReviewDate" < \'%s\'',
167
                    DBDatetime::now()->Format('y-MM-dd')
168
                )
169
            );
170
        } else {
171
            // Review date before
172 View Code Duplication
            if (!empty($params['ReviewDateBefore'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
173
                // TODO Get value from DateField->dataValue() once we have access to form elements here
174
                $nextReviewUnixSec = strtotime(
175
                    ' + 1 day',
176
                    strtotime($params['ReviewDateBefore'])
177
                );
178
                $records = $records->where(
179
                    sprintf(
180
                        "\"NextReviewDate\" < '%s'",
181
                        DBDatetime::create()->setValue($nextReviewUnixSec)->Format('y-MM-dd')
182
                    )
183
                );
184
            }
185
186
            // Review date after
187 View Code Duplication
            if (!empty($params['ReviewDateAfter'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
188
                // TODO Get value from DateField->dataValue() once we have access to form elements here
189
                $records = $records->where(
190
                    sprintf(
191
                        "\"NextReviewDate\" >= '%s'",
192
                        DBDatetime::create()->setValue(strtotime($params['ReviewDateAfter']))->Format('y-MM-dd')
193
                    )
194
                );
195
            }
196
        }
197
198
        // Show virtual pages?
199 View Code Duplication
        if (empty($params["ShowVirtualPages"])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
200
            $virtualPageClasses = ClassInfo::subclassesFor(VirtualPage::class);
201
            $records = $records->where(sprintf(
202
                "\"SiteTree\".\"ClassName\" NOT IN ('%s')",
203
                implode("','", array_values($virtualPageClasses))
204
            ));
205
        }
206
207
        // Owner dropdown
208
        if (!empty($params[ContentReviewOwner::class])) {
209
            $ownerNames = Convert::raw2sql($params[ContentReviewOwner::class]);
210
            $records = $records->filter("OwnerNames:PartialMatch", $ownerNames);
211
        }
212
213
        // Only show pages assigned to the current user?
214
        // This come last because it transforms $records to an ArrayList.
215
        if (!empty($params["OnlyMyPages"])) {
216
            $currentUser = Security::getCurrentUser();
217
218
            $records = $records->filterByCallback(function ($page) use ($currentUser) {
219
                $options = $page->getOptions();
220
221
                foreach ($options->ContentReviewOwners() as $owner) {
222
                    if ($currentUser->ID == $owner->ID) {
223
                        return true;
224
                    }
225
                }
226
227
                return false;
228
            });
229
        }
230
231
        ContentReviewCompatability::done($compatibility);
232
233
        return $records;
234
    }
235
}
236