Passed
Pull Request — master (#326)
by Robbie
04:32
created

FileSubsites   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 145
rs 10
wmc 23

7 Methods

Rating   Name   Duplication   Size   Complexity  
A onBeforeWrite() 0 7 4
A cacheKeyComponent() 0 3 1
A alternateTreeTitle() 0 7 2
A onAfterUpload() 0 9 2
C augmentSQL() 0 32 7
A canEdit() 0 12 3
B updateCMSFields() 0 28 4
1
<?php
2
3
namespace SilverStripe\Subsites\Extensions;
4
5
use SilverStripe\Assets\Folder;
6
use SilverStripe\Forms\DropdownField;
7
use SilverStripe\Forms\FieldList;
8
use SilverStripe\Forms\LiteralField;
9
use SilverStripe\ORM\DataExtension;
10
use SilverStripe\ORM\DataQuery;
11
use SilverStripe\ORM\Queries\SQLSelect;
12
use SilverStripe\Security\Permission;
13
use SilverStripe\Subsites\Model\Subsite;
14
use SilverStripe\Subsites\State\SubsiteState;
15
16
/**
17
 * Extension for the File object to add subsites support
18
 *
19
 * @package subsites
20
 */
21
class FileSubsites extends DataExtension
22
{
23
    // If this is set to true, all folders created will be default be
24
    // considered 'global', unless set otherwise
25
    public static $default_root_folders_global = false;
26
27
    private static $has_one = [
0 ignored issues
show
introduced by
The private property $has_one is not used, and could be removed.
Loading history...
28
        'Subsite' => Subsite::class,
29
    ];
30
31
    /**
32
     * Amends the CMS tree title for folders in the Files & Images section.
33
     * Prefixes a '* ' to the folders that are accessible from all subsites.
34
     */
35
    public function alternateTreeTitle()
36
    {
37
        if ($this->owner->SubsiteID == 0) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $this->owner->SubsiteID of type null|mixed to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
38
            return ' * ' . $this->owner->Title;
39
        }
40
41
        return $this->owner->Title;
42
    }
43
44
    /**
45
     * Add subsites-specific fields to the folder editor.
46
     * @param FieldList $fields
47
     */
48
    public function updateCMSFields(FieldList $fields)
49
    {
50
        if ($this->owner instanceof Folder) {
51
            $sites = Subsite::accessible_sites('CMS_ACCESS_AssetAdmin');
52
            $values = [];
53
            $values[0] = _t(__CLASS__ . '.AllSitesDropdownOpt', 'All sites');
54
            foreach ($sites as $site) {
55
                $values[$site->ID] = $site->Title;
56
            }
57
            ksort($values);
58
            if ($sites) {
59
                //Dropdown needed to move folders between subsites
60
                /** @var @skipUpgrade */
61
                $dropdown = new DropdownField(
62
                    'SubsiteID',
63
                    _t(__CLASS__ . '.SubsiteFieldLabel', 'Subsite'),
64
                    $values
65
                );
66
                $dropdown->addExtraClass('subsites-move-dropdown');
67
                $fields->push($dropdown);
68
                $fields->push(new LiteralField(
69
                    'Message',
70
                    '<p class="message notice">' .
71
                    _t(
72
                        'ASSETADMIN.SUBSITENOTICE',
73
                        'Folders and files created in the main site are accessible by all subsites.'
74
                    )
75
                    . '</p>'
76
                ));
77
            }
78
        }
79
    }
80
81
    /**
82
     * Update any requests to limit the results to the current site
83
     * @param SQLSelect $query
84
     * @param DataQuery|null $dataQuery
85
     */
86
    public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)
87
    {
88
        if (Subsite::$disable_subsite_filter) {
89
            return;
90
        }
91
92
        // If you're querying by ID, ignore the sub-site - this is a bit ugly... (but it was WAYYYYYYYYY worse)
93
        //@TODO I don't think excluding if SiteTree_ImageTracking is a good idea however because of the SS 3.0 api and ManyManyList::removeAll() changing the from table after this function is called there isn't much of a choice
94
95
        $from = $query->getFrom();
96
        if (isset($from['SiteTree_ImageTracking']) || $query->filtersOnID()) {
97
            return;
98
        }
99
100
        $subsiteID = SubsiteState::singleton()->getSubsiteId();
101
        if ($subsiteID === null) {
102
            return;
103
        }
104
105
        // The foreach is an ugly way of getting the first key :-)
106
        foreach ($query->getFrom() as $tableName => $info) {
107
            $where = "\"$tableName\".\"SubsiteID\" IN (0, $subsiteID)";
108
            $query->addWhere($where);
109
            break;
110
        }
111
112
        $sect = array_values($query->getSelect());
113
        $isCounting = strpos($sect[0], 'COUNT') !== false;
114
115
        // Ordering when deleting or counting doesn't apply
116
        if (!$isCounting) {
117
            $query->addOrderBy('"SubsiteID"');
118
        }
119
    }
120
121
    public function onBeforeWrite()
122
    {
123
        if (!$this->owner->ID && !$this->owner->SubsiteID) {
124
            if (self::$default_root_folders_global) {
125
                $this->owner->SubsiteID = 0;
126
            } else {
127
                $this->owner->SubsiteID = SubsiteState::singleton()->getSubsiteId();
128
            }
129
        }
130
    }
131
132
    public function onAfterUpload()
133
    {
134
        // If we have a parent, use it's subsite as our subsite
135
        if ($this->owner->Parent()) {
136
            $this->owner->SubsiteID = $this->owner->Parent()->SubsiteID;
137
        } else {
138
            $this->owner->SubsiteID = SubsiteState::singleton()->getSubsiteId();
139
        }
140
        $this->owner->write();
141
    }
142
143
    public function canEdit($member = null)
144
    {
145
        // Check the CMS_ACCESS_SecurityAdmin privileges on the subsite that owns this group
146
        $subsiteID = SubsiteState::singleton()->getSubsiteId();
147
        if ($subsiteID && $subsiteID == $this->owner->SubsiteID) {
148
            return true;
149
        }
150
151
        return SubsiteState::singleton()->withState(function ($newState) {
152
            $newState->setSubsiteId($this->owner->SubsiteID);
153
154
            return Permission::check(['CMS_ACCESS_AssetAdmin', 'CMS_ACCESS_LeftAndMain']);
155
        });
156
    }
157
158
    /**
159
     * Return a piece of text to keep DataObject cache keys appropriately specific
160
     *
161
     * @return string
162
     */
163
    public function cacheKeyComponent()
164
    {
165
        return 'subsite-' . SubsiteState::singleton()->getSubsiteId();
166
    }
167
}
168