Completed
Push — master ( 2a4315...ac93b3 )
by Nicolaas
01:25
created

code/api/PermissionProviderFactory.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
4
class PermissionProviderFactory extends Object
5
{
6
7
    private static $_instance = null;
8
9
    public static function inst()
10
    {
11
        if(self::$_instance === null) {
12
            self::$_instance = Injector::inst()->get('PermissionProviderFactory');
13
        }
14
15
        return self::$_instance;
16
    }
17
18
    protected $email = '';
19
    protected $firstName = '';
20
    protected $surname = '';
21
    protected $code = '';
22
    protected $name = '';
23
    protected $parentGroup = null;
24
    protected $permissionCode = '';
25
    protected $roleTitle = '';
26
    protected $permissionArray = [];
27
    protected $member = null;
28
29
    public function setEmail($email){$this->email = $email; return $this;}
30
    public function setFirstName($firstName){$this->firstName = $firstName; return $this;}
31
    public function setSurname($surname){$this->surname = $surname; return $this;}
32
    public function setPassword($password){$this->password = $password; return $this;}
0 ignored issues
show
The property password does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
33
    public function setCode($code){$this->code = $code; return $this;}
34
    public function setName($name){$this->name = $name; return $this;}
35
    public function setParentGroup($parentGroup){$this->parentGroup = $parentGroup; return $this;}
36
    public function setPermissionCode($permissionCode){$this->permissionCode = $permissionCode; return $this;}
37
    public function setRoleTitle($roleTitle){$this->roleTitle = $roleTitle; return $this;}
38
    public function setPermissionArray($permissionArray){$this->permissionArray = $permissionArray; return $this;}
39
    public function setMember($member){$this->member = $member; return $this;}
40
41
    /**
42
     *
43
     * @return Group and member, using the default settings
44
     */
45
    function CreateGroupAndMember()
46
    {
47
        $member = $this->CreateDefaultMember(
48
            $this->email,
49
            $this->firstName,
50
            $this->surname,
51
            $this->password
52
        );
53
        $group = $this->CreateGroup(
54
            $this->code,
55
            $this->name,
56
            $this->parentGroup,
57
            $this->permissionCode,
58
            $this->roleTitle,
59
            $this->permissionArray,
60
            $member
61
        );
62
63
        return $group;
64
    }
65
66
67
    /**
68
     * Create a member
69
     * @param       string $email
70
     * @param       string $firstName   OPTIONAL
71
     * @param       string $surname     OPTIONAL
72
     * @param       string $password    OPTIONAL
73
     *
74
     * @return Member
75
     */
76
    public function CreateDefaultMember(
77
        $email,
78
        $firstName = '',
79
        $surname = '',
80
        $password = ''
81
    )
82
    {
83
        if(! $email) {$email = $this->email;}
84
        if(! $firstName) {$firstName = $this->firstName;}
85
        if(! $surname) {$surname = $this->surname;}
86
        if(! $password) {$password = $this->password;}
87
88
        if(! $email) {
89
            $baseURL = Director::absoluteBaseURL();
90
            $baseURL = str_replace('https://', '', $baseURL);
91
            $baseURL = str_replace('http://', '', $baseURL);
92
            $baseURL = trim( $baseURL, '/' );
93
            $email = 'random.email.'.rand(0,999999).'@'.$baseURL;
94
        }
95
        if(! $firstName) {
96
            $firstName = 'Default';
97
        }
98
        if(! $surname) {
99
            $surname = 'User';
100
        }
101
102
        $filter = array('Email' => $email);
103
        $member = DataObject::get_one(
104
            'Member',
105
            $filter,
106
            $cacheDataObjectGetOne = false
107
        );
108
        if (! $member) {
109
            $member = Member::create($filter);
110
        }
111
112
        $member->FirstName = $firstName;
113
        $member->Surname = $surname;
114
        $member->write();
115
        if ($password) {
116
            $member->changePassword($password);
117
            $member->PasswordExpiry = date('Y-m-d');
118
            $member->write();
119
        }
120
121
        return $member;
122
    }
123
124
    /**
125
     * set up a group with permissions, roles, etc...
126
     * also note that this class implements PermissionProvider.
127
     *
128
     * @param string          $code            code for the group - will always be converted to lowercase
129
     * @param string          $name            title for the group
130
     * @param Group | String  $parentGroup     group object that is the parent of the group. You can also provide a string (name / title of group)
131
     * @param string          $permissionCode  Permission Code for the group (e.g. CMS_DO_THIS_OR_THAT)
132
     * @param string          $roleTitle       Role Title - e.g. Store Manager
133
     * @param array           $permissionArray Permission Array - list of permission codes applied to the group
134
     * @param Member | String $member          Default Member added to the group (e.g. [email protected]). You can also provide an email address
135
     */
136
    public function CreateGroup(
137
        $code = '',
138
        $name,
139
        $parentGroup = null,
140
        $permissionCode = '',
141
        $roleTitle = '',
142
        array $permissionArray = [],
143
        $member = null
144
    )
145
    {
146
        if(! $name) {$name = $this->name;}
147
        if(! $code) {$code = $this->code;}
148
        if(! $parentGroup) { $parentGroup = $this->parentGroup;}
149
        if(! $permissionCode) { $permissionCode = $this->permissionCode;}
150
        if(! $permissionArray || count($permissionArray) === 0) { $permissionArray = $this->permissionArray;}
151
        if(! $member) { $member = $this->member;}
152
        if(!$name) {
153
            $name = 'New Group '.rand(0,999999);
154
        }
155
        if(!$code) {
156
            $code = $name;
157
        }
158
        $code = str_replace(' ', '_', $code);
159
        $code = preg_replace("/[\W_]+/u", '', $code);
160
        //changing to lower case seems to be very important
161
        //unidentified bug so far
162
        $code = strtolower($code);
163
164
        $filterArrayForGroup = array('Code' => $code);
165
        $groupDataList = Group::get()->filter($filterArrayForGroup);
166
        $groupCount = $groupDataList->count();
167
        $groupStyle = 'updated';
168
        if ($groupCount > 1) {
169
            user_error("There is more than one group with the $name ($code) Code");
170
        }
171
        if ($groupCount == 0) {
172
            $group = Group::create($filterArrayForGroup);
173
            $groupStyle = 'created';
174
        } else {
175
            $group = $groupDataList->First();
176
        }
177
        $group->Locked = 1;
178
        $group->Title = $name;
179
        $parentGroupStyle = 'updated';
180
        if ($parentGroup) {
181
            DB::alteration_message('adding parent group');
182
            if (is_string($parentGroup)) {
183
                $parentGroupName = $parentGroup;
184
                $parentGroup = DataObject::get_one(
185
                    'Group',
186
                    array('Title' => $parentGroupName),
187
                    $cacheDataObjectGetOne = false
188
                );
189
                if (!$parentGroup) {
190
                    $parentGroup = Group::create();
191
                    $parentGroupStyle = 'created';
192
                    $parentGroup->Title = $parentGroupName;
193
                    $parentGroup->write();
194
                    DB::alteration_message("$parentGroupStyle $parentGroupName", $parentGroupStyle);
195
                }
196
            }
197
            if ($parentGroup) {
198
                $group->ParentID = $parentGroup->ID;
199
            }
200
        }
201
        $group->write();
202
        DB::alteration_message("$groupStyle $name ($code) group", $groupStyle);
203
        $doubleGroups = Group::get()
204
            ->filter(array('Code' => $code))
205
            ->exclude(array('ID' => $group->ID));
206
        if ($doubleGroups->count()) {
207
            DB::alteration_message($doubleGroups->count().' groups with the same name', 'deleted');
208
            $realMembers = $group->Members();
209
            foreach ($doubleGroups as $doubleGroup) {
210
                $fakeMembers = $doubleGroup->Members();
211
                foreach ($fakeMembers as $fakeMember) {
212
                    DB::alteration_message('adding customers: '.$fakeMember->Email, 'created');
213
                    $realMembers->add($fakeMember);
214
                }
215
                DB::alteration_message('deleting double group ', 'deleted');
216
                $doubleGroup->delete();
217
            }
218
        }
219
        if ($permissionCode) {
220
            $permissionCodeCount = DB::query("SELECT * FROM \"Permission\" WHERE \"GroupID\" = '".$group->ID."' AND \"Code\" LIKE '".$permissionCode."'")->numRecords();
221
            if ($permissionCodeCount == 0) {
222
                DB::alteration_message('granting '.$name." permission code $permissionCode ", 'created');
223
                Permission::grant($group->ID, $permissionCode);
224
            } else {
225
                DB::alteration_message($name." permission code $permissionCode already granted");
226
            }
227
        }
228
        //we unset it here to avoid confusion with the
229
        //other codes we use later on
230
        $permissionArray[] = $permissionCode;
231
        unset($permissionCode);
232
        if ($roleTitle) {
233
            $permissionRoleCount = PermissionRole::get()
234
                ->Filter(array('Title' => $roleTitle))
235
                ->Count();
236
            if ($permissionRoleCount > 1) {
237
                db::alteration_message("There is more than one Permission Role with title $roleTitle ($permissionRoleCount)", 'deleted');
238
                $permissionRolesFirst = DataObject::get_one(
239
                    'PermissionRole',
240
                    array('Title' => $roleTitle),
241
                    $cacheDataObjectGetOne = false
242
                );
243
                $permissionRolesToDelete = PermissionRole::get()
244
                    ->Filter(array('Title' => $roleTitle))
245
                    ->Exclude(array('ID' => $permissionRolesFirst->ID));
246
                foreach ($permissionRolesToDelete as $permissionRoleToDelete) {
247
                    db::alteration_message("DELETING double permission role $roleTitle", 'deleted');
248
                    $permissionRoleToDelete->delete();
249
                }
250
            }
251
            elseif ($permissionRoleCount == 1) {
252
                //do nothing
253
                DB::alteration_message("$roleTitle role in place");
254
            } else {
255
                DB::alteration_message("adding $roleTitle role", 'created');
256
                $permissionRole = PermissionRole::create();
257
                $permissionRole->Title = $roleTitle;
258
                $permissionRole->OnlyAdminCanApply = true;
259
                $permissionRole->write();
260
            }
261
            $permissionRole = DataObject::get_one(
262
                'PermissionRole',
263
                array('Title' => $roleTitle),
264
                $cacheDataObjectGetOne = false
265
            );
266
            if ($permissionRole) {
267
                if (is_array($permissionArray) && count($permissionArray)) {
268
                    DB::alteration_message('working with '.implode(', ', $permissionArray));
269
                    foreach ($permissionArray as $permissionRoleCode) {
270
                        $permissionRoleCodeObject = DataObject::get_one(
271
                            'PermissionRoleCode',
272
                            array('Code' => $permissionRoleCode, 'RoleID' => $permissionRole->ID),
273
                            $cacheDataObjectGetOne = false
274
                        );
275
                        $permissionRoleCodeObjectCount = PermissionRoleCode::get()
276
                            ->Filter(array('Code' => $permissionRoleCode, 'RoleID' => $permissionRole->ID))
277
                            ->Count();
278
                        if ($permissionRoleCodeObjectCount > 1) {
279
                            $permissionRoleCodeObjectsToDelete = PermissionRoleCode::get()
280
                                ->Filter(array('Code' => $permissionRoleCode, 'RoleID' => $permissionRole->ID))
281
                                ->Exclude(array('ID' => $permissionRoleCodeObject->ID));
282
                            foreach ($permissionRoleCodeObjectsToDelete as $permissionRoleCodeObjectToDelete) {
283
                                db::alteration_message("DELETING double permission code $permissionRoleCode for ".$permissionRole->Title, 'deleted');
284
                                $permissionRoleCodeObjectToDelete->delete();
285
                            }
286
                            db::alteration_message('There is more than one Permission Role Code in '.$permissionRole->Title." with Code = $permissionRoleCode ($permissionRoleCodeObjectCount)", 'deleted');
287
                        }
288
                        elseif ($permissionRoleCodeObjectCount == 1) {
289
                            //do nothing
290
                        } else {
291
                            $permissionRoleCodeObject = PermissionRoleCode::create();
292
                            $permissionRoleCodeObject->Code = $permissionRoleCode;
293
                            $permissionRoleCodeObject->RoleID = $permissionRole->ID;
294
                        }
295
                        DB::alteration_message('adding '.$permissionRoleCodeObject->Code.' to '.$permissionRole->Title);
296
                        $permissionRoleCodeObject->write();
297
                    }
298
                }
299
                if ($group && $permissionRole) {
300
                    if (DB::query('SELECT COUNT(*) FROM Group_Roles WHERE GroupID = '.$group->ID.' AND PermissionRoleID = '.$permissionRole->ID)->value() == 0) {
301
                        db::alteration_message('ADDING '.$permissionRole->Title.' permission role  to '.$group->Title.' group', 'created');
302
                        $existingGroups = $permissionRole->Groups();
303
                        $existingGroups->add($group);
304
                    } else {
305
                        db::alteration_message('CHECKED '.$permissionRole->Title.' permission role  to '.$group->Title.' group');
306
                    }
307
                } else {
308
                    db::alteration_message('ERROR: missing group or permissionRole', 'deleted');
309
                }
310
            }
311
        }
312
        if ($member) {
313
            if (is_string($member)) {
314
                $email = $member;
315
                $member = $this->CreateDefaultMember($email, $code, $name);
316
            }
317
            if ($member) {
318
                DB::alteration_message(' adding member '.$member->Email.' to group '.$group->Title, 'created');
319
                $member->Groups()->add($group);
320
            }
321
        } else {
322
            DB::alteration_message('No user provided.');
323
        }
324
325
        return $group;
326
    }
327
}
328