Passed
Push — master ( 6e4772...b11769 )
by vistart
04:42
created

UserOrganizationTrait::createBaseOrganization()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 19
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3.0032

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 13
cts 14
cp 0.9286
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 15
nc 3
nop 8
crap 3.0032

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 *  _   __ __ _____ _____ ___  ____  _____
5
 * | | / // // ___//_  _//   ||  __||_   _|
6
 * | |/ // /(__  )  / / / /| || |     | |
7
 * |___//_//____/  /_/ /_/ |_||_|     |_|
8
 * @link https://vistart.me/
9
 * @copyright Copyright (c) 2016 - 2017 vistart
10
 * @license https://vistart.me/license/
11
 */
12
13
namespace rhosocial\organization;
14
15
use rhosocial\organization\queries\MemberQuery;
16
use rhosocial\organization\queries\OrganizationQuery;
17
use rhosocial\organization\rbac\roles\DepartmentCreator;
18
use rhosocial\organization\rbac\roles\OrganizationCreator;
19
use Yii;
20
use yii\base\InvalidConfigException;
21
use yii\base\InvalidParamException;
22
23
/**
24
 * @property string $guidAttribute GUID Attribute.
25
 * @property-read Member[] $ofMembers
26
 * @property-read Organization[] $atOrganizations
27
 *
28
 * @version 1.0
29
 * @author vistart <[email protected]>
30
 */
31
trait UserOrganizationTrait
32
{
33
    public $organizationClass = Organization::class;
34
    public $memberClass = Member::class;
35
    private $noInitOrganization;
36
    private $noInitMember;
37
    public $lastSetUpOrganization;
38
    /**
39
     * @return Organization
40
     */
41
    protected function getNoInitOrganization()
42
    {
43
        if (!$this->noInitOrganization) {
44
            $class = $this->organizationClass;
45
            $this->noInitOrganization = $class::buildNoInitModel();
46
        }
47
        return $this->noInitOrganization;
48
    }
49
    /**
50
     * @return Member
51
     */
52 17
    protected function getNoInitMember()
53
    {
54 17
        if (!$this->noInitMember) {
55 17
            $class = $this->memberClass;
56 17
            $this->noInitMember = $class::buildNoInitModel();
57
        }
58 17
        return $this->noInitMember;
59
    }
60
61
    /**
62
     * 
63
     * @return MemberQuery
64
     */
65 17
    public function getOfMembers()
66
    {
67 17
        return $this->hasMany($this->memberClass, [$this->getNoInitMember()->memberAttribute => $this->guidAttribute])->inverseOf('memberUser');
0 ignored issues
show
Bug introduced by
It seems like hasMany() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
68
    }
69
70
    /**
71
     * 
72
     * @return OrganizationQuery
73
     */
74 8
    public function getAtOrganizations()
75
    {
76 8
        return $this->hasMany($this->organizationClass, [$this->guidAttribute => $this->getNoInitMember()->createdByAttribute])->via('ofMembers');
0 ignored issues
show
Bug introduced by
It seems like hasMany() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
77
    }
78
79
    /**
80
     * Set up organization.
81
     * @param string $name
82
     * @param Organization $parent
83
     * @param string $nickname
84
     * @param integer $gravatar_type
85
     * @param string $gravatar
86
     * @param string $timezone
87
     * @param string $description
88
     * @return boolean Whether indicate the setting-up succeeded or not.
89
     */
90 24
    public function setUpOrganization($name, $parent = null, $nickname = '', $gravatar_type = 0, $gravatar = '', $timezone = 'UTC', $description = '')
0 ignored issues
show
Unused Code introduced by
The parameter $nickname is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $gravatar_type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $gravatar is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $timezone is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $description is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
91
    {
92 24
        $transaction = Yii::$app->db->beginTransaction();
93
        try {
94 24
            $models = $this->createOrganization($name, $parent, $nickname = '', $gravatar_type = 0, $gravatar = '', $timezone = 'UTC', $description = '');
95 24
            $this->setUpBaseOrganization($models);
96 23
            $transaction->commit();
97 1
        } catch (\Exception $ex) {
98 1
            $transaction->rollBack();
99 1
            Yii::error($ex->getMessage(), __METHOD__);
100 1
            throw $ex;
101
        }
102 23
        $this->lastSetUpOrganization = is_array($models) ? $models[0] : $models;
103 23
        return true;
104
    }
105
106
    /**
107
     * Set up organization.
108
     * @param string $name
109
     * @param Organization $parent
110
     * @param string $nickname
111
     * @param integer $gravatar_type
112
     * @param string $gravatar
113
     * @param string $timezone
114
     * @param string $description
115
     * @return boolean Whether indicate the setting-up succeeded or not.
116
     */
117 3
    public function setUpDepartment($name, $parent = null, $nickname = '', $gravatar_type = 0, $gravatar = '', $timezone = 'UTC', $description = '')
0 ignored issues
show
Unused Code introduced by
The parameter $nickname is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $gravatar_type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $gravatar is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $timezone is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $description is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
118
    {
119 3
        if ($parent == null) {
120 1
            throw new InvalidConfigException('Invalid Parent Parameter.');
121
        }
122 2
        $transaction = Yii::$app->db->beginTransaction();
123
        try {
124 2
            $models = $this->createDepartment($name, $parent, $nickname = '', $gravatar_type = 0, $gravatar = '', $timezone = 'UTC', $description = '');
125 2
            $this->setUpBaseOrganization($models);
126 1
            $transaction->commit();
127 1
        } catch (\Exception $ex) {
128 1
            $transaction->rollBack();
129 1
            Yii::error($ex->getMessage(), __METHOD__);
130 1
            throw $ex;
131
        }
132 1
        $this->lastSetUpOrganization = is_array($models) ? $models[0] : $models;
133 1
        return true;
134
    }
135
136
    /**
137
     * Set up base organization.
138
     * @param Organization $models
139
     * @return boolean
140
     * @throws InvalidConfigException
141
     * @throws \Exception
142
     */
143 24
    protected function setUpBaseOrganization($models)
144
    {
145 24
        $model = null;
146 24
        $associatedModels = [];
147 24
        if (is_array($models)) {
148 2
            if (!array_key_exists(0, $models)) {
149 2
                throw new InvalidConfigException('Invalid Organization Model.');
150
            }
151
            $model = $models[0];
152
            $associatedModels = array_key_exists('associatedModels', $models) ? $models['associatedModels'] : [];
153
        } elseif ($models instanceof Organization) {
154 23
            $model = $models;
155
        }
156 23
        $result = $model->register($associatedModels);
157 23
        if ($result instanceof \Exception) {
158
            throw $result;
159
        }
160 23
        if ($result !== true) {
161
            throw new \Exception('Failed to set up.');
162
        }
163 23
        return true;
164
    }
165
166
    /**
167
     * Create organization.
168
     * @param string $name
169
     * @param Organization $parent
170
     * @param string $nickname
171
     * @param string $gravatar_type
172
     * @param string $gravatar
173
     * @param string $timezone
174
     * @param string $description
175
     * @return Organization
176
     */
177 23
    public function createOrganization($name, $parent = null, $nickname = '', $gravatar_type = 0, $gravatar = '', $timezone = 'UTC', $description = '')
178
    {
179 23
        return $this->createBaseOrganization($name, $parent, $nickname, $gravatar_type, $gravatar, $timezone, $description);
180
    }
181
182
    /**
183
     * Create department.
184
     * @param string $name
185
     * @param Organization $parent
186
     * @param string $nickname
187
     * @param string $gravatar_type
188
     * @param string $gravatar
189
     * @param string $timezone
190
     * @param string $description
191
     * @return Organization
192
     */
193 1
    public function createDepartment($name, $parent = null, $nickname = '', $gravatar_type = 0, $gravatar = '', $timezone = 'UTC', $description = '')
194
    {
195 1
        return $this->createBaseOrganization($name, $parent, $nickname, $gravatar_type, $gravatar, $timezone, $description, Organization::TYPE_DEPARTMENT);
196
    }
197
198
    /**
199
     * Create Base Organization.
200
     * @param string $name
201
     * @param Organization $parent
202
     * @param string $nickname
203
     * @param integer $gravatar_type
204
     * @param string $gravatar
205
     * @param string $timezone
206
     * @param string $description
207
     * @param integer $type
208
     * @return Organization
209
     * @throws InvalidParamException throw if setting parent failed. Possible reasons include:
210
     * - The parent is itself.
211
     * - The parent has already been its ancestor.
212
     * - The current organization has reached the limit of ancestors.
213
     */
214 23
    protected function createBaseOrganization($name, $parent = null, $nickname = '', $gravatar_type = 0, $gravatar = '', $timezone = 'UTC', $description = '', $type = Organization::TYPE_ORGANIZATION)
215
    {
216 23
        $class = $this->organizationClass;
217
        $profileConfig = [
218 23
            'name' => $name,
219 23
            'nickname' => $nickname,
220 23
            'gravatar_type' => $gravatar_type,
221 23
            'gravatar' => $gravatar,
222 23
            'timezone' => $timezone,
223 23
            'description' => $description,
224
        ];
225 23
        $organization = new $class(['type' => $type, 'creator' => $this, 'profileConfig' => $profileConfig]);
226 23
        if (empty($parent)) {
227 23
            $organization->setNullParent();
228 4
        } elseif ($organization->setParent($parent) === false) {
229
            throw new InvalidParamException("Failed to set parent.");
230
        }
231 23
        return $organization;
232
    }
233
234
    /**
235
     * Revoke organization.
236
     * @param static|string|integer $organization
237
     * @param boolean $revokeIfHasChildren
238
     * @throws InvalidParamException throw if current user is not the creator of organization.
239
     */
240 1
    public function revokeOrganization($organization, $revokeIfHasChildren = false)
0 ignored issues
show
Unused Code introduced by
The parameter $revokeIfHasChildren is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
241
    {
242 1
        if (!($organization instanceof $this->organizationClass))
243
        {
244
            $class = $this->organizationClass;
245
            if (is_int($organization)) {
246
                $organization = $class::find()->id($organization)->one();
247
            } elseif (is_string($organization)) {
248
                $organization = $class::find()->guid($organization)->one();
249
            }
250
        }
251 1
        if (!$this->isOrganizationCreator($organization)) {
252
            throw new InvalidParamException('You are not the creator of the this organization and have no right to revoke it.');
253
        }
254 1
        $transaction = Yii::$app->db->beginTransaction();
255
        try {
256 1
            $result = $organization->deregister();
257 1
            if ($result instanceof \Exception){
258
                throw $result;
259
            }
260 1
            if ($result !== true) {
261
                throw new InvalidParamException();
262
            }
263 1
            $transaction->commit();
264
        } catch (\Exception $ex) {
265
            $transaction->rollBack();
266
            Yii::error($ex->getMessage(), __METHOD__);
267
            throw $ex;
268
        }
269 1
        return true;
270
    }
271
272
    /**
273
     * 
274
     * @param Organization $organization
275
     */
276 1
    public function isOrganizationCreator($organization)
277
    {
278 1
        $member = $organization->getMember($this);
279 1
        if (!$member) {
280
            return false;
281
        }
282 1
        return $member->isCreator();
283
    }
284
285
    /**
286
     * 
287
     * @param Organization $organization
288
     */
289 2
    public function isOrganizationAdministrator($organization)
290
    {
291 2
        $member = $organization->getMember($this);
292 2
        if (!$member) {
293 2
            return false;
294
        }
295 2
        return $member->isAdministrator();
296
    }
297
}
298