Completed
Push — master ( e72c23...de047a )
by Jeroen
25:41
created

ElggExtender::getURL()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 7
Ratio 100 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 7
loc 7
ccs 4
cts 4
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * The base class for \ElggEntity extenders.
4
 *
5
 * Extenders allow you to attach extended information to an
6
 * \ElggEntity.  Core supports two: \ElggAnnotation and \ElggMetadata.
7
 *
8
 * Saving the extender data to database is handled by the child class.
9
 *
10
 * @package    Elgg.Core
11
 * @subpackage DataModel.Extender
12
 * @see        \ElggAnnotation
13
 * @see        \ElggMetadata
14
 *
15
 * @property string $type         annotation or metadata (read-only after save)
16
 * @property int    $id           The unique identifier (read-only)
17
 * @property int    $entity_guid  The GUID of the entity that this extender describes
18
 * @property int    $owner_guid   The GUID of the owner of this extender
19
 * @property int    $access_id    Specifies the visibility level of this extender
20
 * @property string $name         The name of this extender
21
 * @property mixed  $value        The value of the extender (int or string)
22
 * @property int    $time_created A UNIX timestamp of when the extender was created (read-only, set on first save)
23
 * @property string $value_type   'integer' or 'text'
24
 * @property string $enabled      Is this extender enabled ('yes' or 'no')
25
 */
26
abstract class ElggExtender extends \ElggData {
27
28
	/**
29
	 * (non-PHPdoc)
30
	 *
31
	 * @see \ElggData::initializeAttributes()
32
	 *
33
	 * @return void
34
	 */
35 3588
	protected function initializeAttributes() {
36 3588
		parent::initializeAttributes();
37
38 3588
		$this->attributes['type'] = null;
39 3588
		$this->attributes['id'] = null;
40 3588
		$this->attributes['entity_guid'] = null;
41 3588
		$this->attributes['owner_guid'] = null;
42 3588
		$this->attributes['access_id'] = ACCESS_PRIVATE;
43 3588
		$this->attributes['enabled'] = 'yes';
44 3588
	}
45
46
	/**
47
	 * Set an attribute
48
	 *
49
	 * @param string $name  Name
50
	 * @param mixed  $value Value
51
	 * @return void
52
	 */
53 4
	public function __set($name, $value) {
54 4
		if ($name === 'access_id' && $this instanceof ElggMetadata) {
55
			$value = ACCESS_PUBLIC;
56
		}
57 4
		$this->attributes[$name] = $value;
58 4
		if ($name == 'value') {
59
			$this->attributes['value_type'] = self::detectValueType($value);
60
		}
61 4
	}
62
63
	/**
64
	 * Set the value of the extender
65
	 *
66
	 * @param mixed  $value      The value being set
67
	 * @param string $value_type The type of the : 'integer' or 'text'
68
	 * @return void
69
	 * @since 1.9
70
	 */
71
	public function setValue($value, $value_type = '') {
72
		$this->attributes['value'] = $value;
73
		$this->attributes['value_type'] = self::detectValueType($value, $value_type);
74
	}
75
76
	/**
77
	 * Gets an attribute
78
	 *
79
	 * @param string $name Name
80
	 * @return mixed
81
	 */
82 3587
	public function __get($name) {
83 3587
		if (array_key_exists($name, $this->attributes)) {
84 3587
			if ($name == 'value') {
85 3422
				switch ($this->attributes['value_type']) {
86 3422
					case 'integer' :
87 11
						return (int) $this->attributes['value'];
88
						break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
89 3417
					case 'text' :
90 3417
						return $this->attributes['value'];
91
						break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
92
					default :
93
						$msg = "{$this->attributes['value_type']} is not a supported \ElggExtender value type.";
94
						throw new \UnexpectedValueException($msg);
95
						break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
96
				}
97
			}
98
99 3587
			if ($name === 'access_id' && $this instanceof ElggMetadata) {
100 126
				return ACCESS_PUBLIC;
101
			}
102
103 3587
			return $this->attributes[$name];
104
		}
105
106 2
		return null;
107
	}
108
109
	/**
110
	 * Get the GUID of the extender's owner entity.
111
	 *
112
	 * @return int The owner GUID
113
	 */
114
	public function getOwnerGUID() {
115
		return $this->owner_guid;
116
	}
117
118
	/**
119
	 * Get the entity that owns this extender
120
	 *
121
	 * @return \ElggEntity
122
	 */
123
	public function getOwnerEntity() {
124
		return get_entity($this->owner_guid);
125
	}
126
127
	/**
128
	 * Get the entity this describes.
129
	 *
130
	 * @return \ElggEntity The entity
131
	 */
132 55
	public function getEntity() {
133 55
		return get_entity($this->entity_guid);
134
	}
135
136
	/**
137
	 * Returns if a user can edit this entity extender.
138
	 *
139
	 * @param int $user_guid The GUID of the user doing the editing
140
	 *                      (defaults to currently logged in user)
141
	 *
142
	 * @return bool
143
	 * @see elgg_set_ignore_access()
144
	 */
145
	abstract public function canEdit($user_guid = 0);
146
147
	/**
148
	 * {@inheritdoc}
149
	 */
150
	public function toObject() {
151
		$object = new \stdClass();
152
		$object->id = $this->id;
153
		$object->entity_guid = $this->entity_guid;
154
		$object->owner_guid = $this->owner_guid;
155
		$object->name = $this->name;
156
		$object->value = $this->value;
157
		$object->time_created = date('c', $this->getTimeCreated());
158
		$object->read_access = $this->access_id;
159
		$params = [
160
			$this->getSubtype() => $this, // deprecated use
161
			$this->getType() => $this,
162
		];
163
		if (_elgg_services()->hooks->hasHandler('to:object', $this->getSubtype())) {
164
			_elgg_services()->deprecation->sendNotice("Triggering 'to:object' hook by extender name '{$this->getSubtype()}' has been deprecated. "
165
			. "Use the generic 'to:object','{$this->getType()}' hook instead.", '2.3');
166
			$object = _elgg_services()->hooks->trigger('to:object', $this->getSubtype(), $params, $object);
167
		}
168
		return _elgg_services()->hooks->trigger('to:object', $this->getType(), $params, $object);
169
	}
170
171
	/*
172
	 * SYSTEM LOG INTERFACE
173
	 */
174
175
	/**
176
	 * Return an identification for the object for storage in the system log.
177
	 * This id must be an integer.
178
	 *
179
	 * @return int
180
	 */
181 145
	public function getSystemLogID() {
182 145
		return $this->id;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->id; of type integer|boolean adds the type boolean to the return on line 182 which is incompatible with the return type declared by the interface Loggable::getSystemLogID of type integer.
Loading history...
183
	}
184
185
	/**
186
	 * Return a type of extension.
187
	 *
188
	 * @return string
189
	 */
190 169
	public function getType() {
191 169
		return $this->type;
192
	}
193
194
	/**
195
	 * Return a subtype. For metadata & annotations this is the 'name' and
196
	 * for relationship this is the relationship type.
197
	 *
198
	 * @return string
199
	 */
200 169
	public function getSubtype() {
201 169
		return $this->name;
202
	}
203
204
	/**
205
	 * Get a url for this extender.
206
	 *
207
	 * Plugins can register for the 'extender:url', <type> plugin hook to
208
	 * customize the url for an annotation or metadata.
209
	 *
210
	 * @return string
211
	 */
212 6 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...
213
214 6
		$params = ['extender' => $this];
215 6
		$url = _elgg_services()->hooks->trigger('extender:url', $this->getType(), $params, '');
216
217 6
		return elgg_normalize_url($url);
218
	}
219
220
	/**
221
	 * Detect the value_type for a value to be stored as metadata or an annotation
222
	 *
223
	 * @param mixed  $value      The value
224
	 * @param string $value_type If specified as "text" or "integer", overrides the detection.
225
	 *
226
	 * @return string
227
	 * @access private
228
	 * @internal
229
	 */
230 3587
	public static function detectValueType($value, $value_type = "") {
231 3587
		if ($value_type === 'integer' || $value_type === 'text') {
232 93
			return $value_type;
233
		}
234
235 3587
		return is_int($value) ? 'integer' : 'text';
236
	}
237
}
238