Issues (144)

src/Extensions/FileSubsites.php (1 issue)

1
<?php
2
3
namespace SilverStripe\Subsites\Extensions;
4
5
use SilverStripe\Assets\File;
6
use SilverStripe\ORM\DataExtension;
7
use SilverStripe\ORM\DataQuery;
8
use SilverStripe\ORM\Queries\SQLSelect;
9
use SilverStripe\Security\Permission;
10
use SilverStripe\Subsites\Model\Subsite;
11
use SilverStripe\Subsites\State\SubsiteState;
12
13
/**
14
 * Extension for the File object to add subsites support
15
 *
16
 * @package subsites
17
 */
18
class FileSubsites extends DataExtension
19
{
20
    /**
21
     * If this is set to true, all folders created will be default be considered 'global', unless set otherwise
22
     *
23
     * @config
24
     * @var bool
25
     */
26
    private static $default_root_folders_global = false;
27
28
    private static $has_one = [
29
        'Subsite' => Subsite::class,
30
    ];
31
32
    /**
33
     * Amends the CMS tree title for folders in the Files & Images section.
34
     * Prefixes a '* ' to the folders that are accessible from all subsites.
35
     */
36
    public function alternateTreeTitle()
37
    {
38
        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 mixed|null 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...
39
            return ' * ' . $this->owner->Title;
40
        }
41
42
        return $this->owner->Title;
43
    }
44
45
    /**
46
     * Update any requests to limit the results to the current site
47
     * @param SQLSelect $query
48
     * @param DataQuery|null $dataQuery
49
     */
50
    public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)
51
    {
52
        if (Subsite::$disable_subsite_filter) {
53
            return;
54
        }
55
        if ($dataQuery && $dataQuery->getQueryParam('Subsite.filter') === false) {
56
            return;
57
        }
58
59
        // If you're querying by ID, ignore the sub-site - this is a bit ugly... (but it was WAYYYYYYYYY worse)
60
        // @TODO I don't think excluding if SiteTree_ImageTracking is a good idea however because of the SS 3.0 api and
61
        // ManyManyList::removeAll() changing the from table after this function is called there isn't much of a choice
62
63
        $from = $query->getFrom();
64
        if (isset($from['SiteTree_ImageTracking']) || $query->filtersOnID()) {
65
            return;
66
        }
67
68
        $subsiteID = SubsiteState::singleton()->getSubsiteId();
69
        if ($subsiteID === null) {
70
            return;
71
        }
72
73
        // The foreach is an ugly way of getting the first key :-)
74
        foreach ($query->getFrom() as $tableName => $info) {
75
            $where = "\"$tableName\".\"SubsiteID\" IN (0, $subsiteID)";
76
            $query->addWhere($where);
77
            break;
78
        }
79
80
        $sect = array_values($query->getSelect());
81
        $isCounting = strpos($sect[0], 'COUNT') !== false;
82
83
        // Ordering when deleting or counting doesn't apply
84
        if (!$isCounting) {
85
            $query->addOrderBy('"SubsiteID"');
86
        }
87
    }
88
89
    public function onBeforeWrite()
90
    {
91
        if (!$this->owner->ID && !$this->owner->SubsiteID) {
92
            if ($this->owner->config()->get('default_root_folders_global')) {
93
                $this->owner->SubsiteID = 0;
94
            } else {
95
                $this->owner->SubsiteID = SubsiteState::singleton()->getSubsiteId();
96
            }
97
        }
98
    }
99
100
    public function onAfterUpload()
101
    {
102
        // If we have a parent, use it's subsite as our subsite
103
        if ($this->owner->Parent()) {
104
            $this->owner->SubsiteID = $this->owner->Parent()->SubsiteID;
105
        } else {
106
            $this->owner->SubsiteID = SubsiteState::singleton()->getSubsiteId();
107
        }
108
        $this->owner->write();
109
    }
110
111
    public function canEdit($member = null)
112
    {
113
        // Opt out of making opinions if no subsite ID is set yet
114
        if (!$this->owner->SubsiteID) {
115
            return null;
116
        }
117
118
        // Check the CMS_ACCESS_SecurityAdmin privileges on the subsite that owns this group
119
        $subsiteID = SubsiteState::singleton()->getSubsiteId();
120
        if ($subsiteID && $subsiteID == $this->owner->SubsiteID) {
121
            return true;
122
        }
123
124
        return SubsiteState::singleton()->withState(function (SubsiteState $newState) use ($member) {
125
            $newState->setSubsiteId($this->owner->SubsiteID);
126
127
            return $this->owner->getPermissionChecker()->canEdit($this->owner->ID, $member);
128
        });
129
    }
130
131
    /**
132
     * Return a piece of text to keep DataObject cache keys appropriately specific
133
     *
134
     * @return string
135
     */
136
    public function cacheKeyComponent()
137
    {
138
        return 'subsite-' . SubsiteState::singleton()->getSubsiteId();
139
    }
140
}
141