Completed
Push — master ( aba420...85fb84 )
by Franco
01:29
created

Lumberjack::stageChildren()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 27
Code Lines 17

Duplication

Lines 3
Ratio 11.11 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 3
loc 27
rs 8.439
cc 6
eloc 17
nc 8
nop 1
1
<?php
2
3
namespace SilverStripe\Lumberjack\Model;
4
5
use Exception;
6
use SilverStripe\Admin\LeftAndMain;
7
use SilverStripe\CMS\Model\SiteTree;
8
use SilverStripe\CMS\Model\SiteTreeExtension;
9
use SilverStripe\Control\Controller;
10
use SilverStripe\Core\Config\Config;
11
use SilverStripe\Forms\FieldList;
12
use SilverStripe\Forms\GridField\GridField;
13
use SilverStripe\Forms\Tab;
14
use SilverStripe\Lumberjack\Forms\GridFieldConfig_Lumberjack;
15
use SilverStripe\ORM\DataList;
16
use SilverStripe\ORM\DataObject;
17
use SilverStripe\Versioned\Versioned;
18
19
/**
20
 * Class Lumberjack
21
 *
22
 * Add this classes to SiteTree classes which children should be hidden.
23
 *
24
 * @package silverstripe
25
 * @subpackage lumberjack
26
 *
27
 * @author Michael Strong <[email protected]>
28
 */
29
class Lumberjack extends SiteTreeExtension
30
{
31
    /**
32
     * Loops through subclasses of the owner (intended to be SiteTree) and checks if they've been hidden.
33
     *
34
     * @return array
35
     **/
36
    public function getExcludedSiteTreeClassNames()
37
    {
38
        $classes = array();
39
        $siteTreeClasses = $this->owner->allowedChildren();
40
41
        foreach ($siteTreeClasses as $class) {
42
            if (Config::inst()->get($class, 'show_in_sitetree') === false) {
43
                $classes[$class] = $class;
44
            }
45
        }
46
47
        return $classes;
48
    }
49
50
    /**
51
     * This is responsible for adding the child pages tab and gridfield.
52
     *
53
     * @param FieldList $fields
54
     */
55
    public function updateCMSFields(FieldList $fields)
56
    {
57
        $excluded = $this->owner->getExcludedSiteTreeClassNames();
58
        if (!empty($excluded)) {
59
            $pages = $this->getLumberjackPagesForGridfield($excluded);
60
            $gridField = GridField::create(
61
                'ChildPages',
62
                $this->getLumberjackTitle(),
63
                $pages,
64
                $this->getLumberjackGridFieldConfig()
65
            );
66
67
            $tab = Tab::create('ChildPages', $this->getLumberjackTitle(), $gridField);
68
            $fields->insertAfter($tab, 'Main');
0 ignored issues
show
Documentation introduced by
'Main' is of type string, but the function expects a object<SilverStripe\Forms\FormField>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
69
        }
70
    }
71
72
    /**
73
     * Return children in the stage site.
74
     *
75
     * @param bool $showAll Include all of the elements, even those not shown in the menus. Only applicable when
76
     *                      extension is applied to {@link SiteTree}.
77
     * @return DataList
78
     */
79
    public function stageChildren($showAll = false)
80
    {
81
        $config = $this->owner->config();
82
        $hideFromHierarchy = $config->get('hide_from_hierarchy');
83
        $hideFromCMSTree = $config->get('hide_from_cms_tree');
84
        $baseClass = $this->owner->baseClass();
85
86
        $staged = $baseClass::get()
87
            ->filter('ParentID', (int)$this->owner->ID)
88
            ->exclude('ID', (int)$this->owner->ID);
89
90
        if ($hideFromHierarchy) {
91
            $staged = $staged->exclude('ClassName', $hideFromHierarchy);
92
        }
93
94
        if ($hideFromCMSTree && $this->showingCMSTree()) {
0 ignored issues
show
Bug introduced by
The method showingCMSTree() does not seem to exist on object<SilverStripe\Lumberjack\Model\Lumberjack>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
95
            $staged = $staged->exclude('ClassName', $hideFromCMSTree);
96
        }
97
98 View Code Duplication
        if (!$showAll && DataObject::getSchema()->fieldSpec($this->owner, 'ShowInMenus')) {
0 ignored issues
show
Bug Best Practice introduced by
The expression \SilverStripe\ORM\DataOb...->owner, 'ShowInMenus') of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
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...
99
            $staged = $staged->filter('ShowInMenus', 1);
100
        }
101
102
        $this->owner->extend("augmentStageChildren", $staged, $showAll);
103
        $this->excludeSiteTreeClassNames($staged);
104
        return $staged;
105
    }
106
107
    /**
108
     * Excludes any hidden owner subclasses
109
     * @param DataList $list
110
     */
111
    protected function excludeSiteTreeClassNames($list)
112
    {
113
        $classNames = $this->owner->getExcludedSiteTreeClassNames();
114
        if ($this->shouldFilter() && count($classNames)) {
115
            // Filter the SiteTree
116
            $list->exclude('ClassName', $classNames);
117
        }
118
    }
119
120
    /**
121
     * Return children in the live site, if it exists.
122
     *
123
     * @param bool $showAll              Include all of the elements, even those not shown in the menus. Only
124
     *                                   applicable when extension is applied to {@link SiteTree}.
125
     * @param bool $onlyDeletedFromStage Only return items that have been deleted from stage
126
     * @return DataList
127
     * @throws Exception
128
     */
129
    public function liveChildren($showAll = false, $onlyDeletedFromStage = false)
130
    {
131
        if (!$this->owner->hasExtension(Versioned::class)) {
132
            throw new Exception('Hierarchy->liveChildren() only works with Versioned extension applied');
133
        }
134
135
        $config = $this->owner->config();
136
        $hideFromHierarchy = $config->get('hide_from_hierarchy');
137
        $hideFromCMSTree = $config->get('hide_from_cms_tree');
138
        $baseClass = $this->owner->baseClass();
139
140
        $children = $baseClass::get()
141
            ->filter('ParentID', (int)$this->owner->ID)
142
            ->exclude('ID', (int)$this->owner->ID)
143
            ->setDataQueryParam(array(
144
                'Versioned.mode' => $onlyDeletedFromStage ? 'stage_unique' : 'stage',
145
                'Versioned.stage' => 'Live'
146
            ));
147
148
        if ($hideFromHierarchy) {
149
            $children = $children->exclude('ClassName', $hideFromHierarchy);
150
        }
151
152
        if ($hideFromCMSTree && $this->showingCMSTree()) {
0 ignored issues
show
Bug introduced by
The method showingCMSTree() does not seem to exist on object<SilverStripe\Lumberjack\Model\Lumberjack>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
153
            $children = $children->exclude('ClassName', $hideFromCMSTree);
154
        }
155
156 View Code Duplication
        if (!$showAll && DataObject::getSchema()->fieldSpec($this->owner, 'ShowInMenus')) {
0 ignored issues
show
Bug Best Practice introduced by
The expression \SilverStripe\ORM\DataOb...->owner, 'ShowInMenus') of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
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...
157
            $children = $children->filter('ShowInMenus', 1);
158
        }
159
        $this->excludeSiteTreeClassNames($children);
160
161
        return $children;
162
    }
163
164
    /**
165
     * This returns the title for the tab and GridField. This can be overwritten
166
     * in the owner class.
167
     *
168
     * @return string
169
     */
170
    protected function getLumberjackTitle()
171
    {
172
        if (method_exists($this->owner, 'getLumberjackTitle')) {
173
            return $this->owner->getLumberjackTitle();
174
        }
175
176
        return _t('Lumberjack.TabTitle', 'Child Pages');
177
    }
178
179
    /**
180
     * This returns the gird field config for the lumberjack gridfield.
181
     *
182
     * @return GridFieldConfig_Lumberjack
183
     */
184
    protected function getLumberjackGridFieldConfig()
185
    {
186
        if (method_exists($this->owner, 'getLumberjackGridFieldConfig')) {
187
            return $this->owner->getLumberjackGridFieldConfig();
0 ignored issues
show
Bug introduced by
The method getLumberjackGridFieldConfig() does not exist on SilverStripe\ORM\DataObject. Did you maybe mean config()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
188
        }
189
190
        return GridFieldConfig_Lumberjack::create();
191
    }
192
193
    /**
194
     * Checks if we're on a controller where we should filter. ie. Are we loading the SiteTree?
195
     * NB: This only checks the current controller. See https://github.com/silverstripe/silverstripe-lumberjack/pull/60
196
     * for a discussion around this.
197
     *
198
     * @return bool
199
     */
200
    protected function shouldFilter()
201
    {
202
        $controller = Controller::curr();
203
204
        // relevant only for CMS
205
        if (!($controller instanceof LeftAndMain)) {
206
            return false;
207
        }
208
209
        return in_array($controller->getAction(), [
210
            'index', 'show', 'treeview', 'listview', 'getsubtree'
211
        ]);
212
    }
213
214
    /**
215
     * Returns list of pages for the CMS gridfield
216
     *
217
     * This also allows the owner class to override this method, e.g. to provide custom ordering.
218
     *
219
     * @var array $excluded     List of class names excluded from the SiteTree
220
     * @return DataList
221
     */
222
    public function getLumberjackPagesForGridfield($excluded = array())
223
    {
224
        if (method_exists($this->owner, 'getLumberjackPagesForGridfield')) {
225
            return $this->owner->getLumberjackPagesForGridfield($excluded);
226
        }
227
228
        return SiteTree::get()->filter([
229
            'ParentID' => $this->owner->ID,
230
            'ClassName' => $excluded,
231
        ]);
232
    }
233
}
234