Passed
Push — master ( 22cae2...2bd8df )
by Jeroen
09:59
created

ElggAccessCollection::getDisplayName()   B

Complexity

Conditions 6
Paths 3

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 14
nc 3
nop 0
dl 0
loc 26
rs 8.439
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Access collection class
5
 *
6
 * @package    Elgg.Core
7
 * @subpackage Core
8
 *
9
 * @property-read int    $id         The unique identifier (read-only)
10
 * @property      int    $owner_guid GUID of the owner
11
 * @property      string $name       Name of the collection
12
 */
13
class ElggAccessCollection extends ElggData {
14
15
	/**
16
	 * Create an access collection object
17
	 *
18
	 * @param stdClass $row Database row
19
	 * @throws InvalidArgumentException
20
	 */
21 View Code Duplication
	public function __construct(stdClass $row = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
22
		$this->initializeAttributes();
23
24
		foreach ((array) $row as $key => $value) {
25
			$this->attributes[$key] = $value;
26
		}
27
	}
28
29
	/**
30
	 * Initialize the attributes array
31
	 *
32
	 * @see ElggData::initializeAttributes()
33
	 * @return void
34
	 */
35 View Code Duplication
	protected function initializeAttributes() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
36
		parent::initializeAttributes();
37
38
		$this->attributes['id'] = null;
39
		$this->attributes['owner_guid'] = null;
40
		$this->attributes['name'] = null;
41
	}
42
43
	/**
44
	 * Set an attribute
45
	 *
46
	 * @param string $name  Name
47
	 * @param mixed  $value Value
48
	 * @return void
49
	 * @throws RuntimeException
50
	 */
51
	public function __set($name, $value) {
52
		if (in_array($name, ['id', 'owner_guid'])) {
53
			throw new RuntimeException("$name can not be set at runtime");
54
		}
55
		$this->attributes[$name] = $value;
56
	}
57
58
	/**
59
	 * Get an attribute
60
	 *
61
	 * @param string $name Name
62
	 * @return mixed
63
	 */
64
	public function __get($name) {
65
		if (array_key_exists($name, $this->attributes)) {
66
			return $this->attributes[$name];
67
		}
68
69
		return null;
70
	}
71
72
	/**
73
	 * Returns owner entity of the collection
74
	 * @return \ElggEntity|false
75
	 */
76
	public function getOwnerEntity() {
77
		return _elgg_services()->entityTable->get($this->owner_guid);
78
	}
79
80
	/**
81
	 * Get readable access level name for this collection
82
	 * @return string
83
	 */
84
	public function getDisplayName() {
85
86
		$filter = function($name = null) {
87
			if (!isset($name)) {
88
				$name = _elgg_services()->translator->translate('access:limited:label');
89
			}
90
			$params = [
91
				'access_collection' => $this,
92
			];
93
			return _elgg_services()->hooks->trigger('access_collection:name', $this->getType(), $params, $name);
94
		};
95
96
		$user = _elgg_services()->session->getLoggedInUser();
97
		$owner = $this->getOwnerEntity();
98
		if (!$user || !$owner) {
99
			// User is not logged in or does not access to the owner entity:
100
			// return default 'Limited' label
101
			return $filter();
102
		}
103
		
104
		if ($user->isAdmin() || $owner->guid == $user->guid) {
105
			return $filter($this->name);
106
		}
107
108
		return $filter();
109
	}
110
111
	/**
112
	 * {@inheritdoc}
113
	 */
114
	public function save() {
115
		if ($this->id > 0) {
116
			return _elgg_services()->accessCollections->rename($this->id, $this->name);
0 ignored issues
show
Bug Compatibility introduced by
The expression _elgg_services()->access...this->id, $this->name); of type integer|false adds the type integer to the return on line 116 which is incompatible with the return type declared by the abstract method ElggData::save of type boolean.
Loading history...
117
		} else {
118
			return _elgg_services()->accessCollections->create($this->name, $this->owner_guid);
0 ignored issues
show
Bug Compatibility introduced by
The expression _elgg_services()->access...me, $this->owner_guid); of type false|integer adds the type integer to the return on line 118 which is incompatible with the return type declared by the abstract method ElggData::save of type boolean.
Loading history...
119
		}
120
	}
121
122
	/**
123
	 * {@inheritdoc}
124
	 */
125
	public function delete() {
126
		return _elgg_services()->accessCollections->delete($this->id);
127
	}
128
129
	/**
130
	 * Check if user can this collection
131
	 *
132
	 * @param int $user_guid GUID of the user
133
	 * @return bool
134
	 */
135
	public function canEdit($user_guid = null) {
136
		return _elgg_services()->accessCollections->canEdit($this->id, $user_guid);
137
	}
138
139
	/**
140
	 * Returns members of the access collection
141
	 *
142
	 * @param array $options ege options
143
	 * @return ElggEntity|int|false
144
	 */
145
	public function getMembers(array $options = []) {
146
		return _elgg_services()->accessCollections->getMembers($this->id, $options);
147
	}
148
149
	/**
150
	 * Checks if user is already in access collection
151
	 *
152
	 * @param int $member_guid GUID of the user
153
	 * @return bool
154
	 */
155
	public function hasMember($member_guid = 0) {
156
		return _elgg_services()->accessCollections->hasUser($member_guid, $this->id);
157
	}
158
159
	/**
160
	 * Adds a new member to access collection
161
	 *
162
	 * @param int $member_guid GUID of the user
163
	 * @return bool
164
	 */
165
	public function addMember($member_guid = 0) {
166
		return _elgg_services()->accessCollections->addUser($member_guid, $this->id);
167
	}
168
169
	/**
170
	 * Removes a user from access collection
171
	 *
172
	 * @param int $member_guid GUID of the user
173
	 * @return bool
174
	 */
175
	public function removeMember($member_guid = 0) {
176
		return _elgg_services()->accessCollections->removeUser($member_guid, $this->id);
177
	}
178
179
	/**
180
	 * {@inheritdoc}
181
	 */
182 View Code Duplication
	public function getURL() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
183
		$type = $this->getType();
184
		$params = [
185
			'access_collection' => $this,
186
		];
187
		$url = _elgg_services()->hooks->trigger('access_collection:url', $type, $params, $url);
0 ignored issues
show
Bug introduced by
The variable $url seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
188
		return elgg_normalize_url($url);
189
	}
190
191
	/**
192
	 * {@inheritdoc}
193
	 */
194 View Code Duplication
	public function toObject() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
195
		$object = new stdClass();
196
		$object->type = $this->getType();
197
		$object->subtype = $this->getSubtype();
198
		$object->id = $this->id;
199
		$object->owner_guid = $this->owner_guid;
200
		$object->name = $this->name;
201
202
		$params = [
203
			'access_collection' => $this,
204
		];
205
		return _elgg_services()->hooks->trigger('to:object', 'access_collection', $params, $object);
206
	}
207
208
	/**
209
	 * {@inheritdoc}
210
	 */
211
	public function getSystemLogID() {
212
		return $this->id;
213
	}
214
215
	/**
216
	 * {@inheritdoc}
217
	 */
218
	public function getObjectFromID($id) {
219
		return _elgg_services()->accessCollections->get($id);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return _elgg_services()-...sCollections->get($id); (array) is incompatible with the return type declared by the interface Loggable::getObjectFromID of type ElggEntity.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
220
	}
221
222
	/**
223
	 * {@inheritdoc}
224
	 */
225
	public function getType() {
226
		return 'access_collection';
227
	}
228
229
	/**
230
	 * {@inheritdoc}
231
	 */
232
	public function getSubtype() {
233
		return $this->name;
234
	}
235
236
}
237