1 | <?php |
||
2 | /** |
||
3 | * Relationship class. |
||
4 | * |
||
5 | * @package Elgg.Core |
||
6 | * @subpackage Core |
||
7 | * |
||
8 | * @property int $id The unique identifier (read-only) |
||
9 | * @property int $guid_one The GUID of the subject of the relationship |
||
10 | * @property string $relationship The type of the relationship (limit of 50 characters long) |
||
11 | * @property int $guid_two The GUID of the target of the relationship |
||
12 | * @property int $time_created A UNIX timestamp of when the relationship was created (read-only, set on first save) |
||
13 | */ |
||
14 | class ElggRelationship extends \ElggData { |
||
15 | // database column limit |
||
16 | const RELATIONSHIP_LIMIT = 50; |
||
17 | |||
18 | /** |
||
19 | * Create a relationship object |
||
20 | * |
||
21 | * @param \stdClass $row Database row |
||
22 | * @throws InvalidArgumentException |
||
23 | */ |
||
24 | 162 | public function __construct(\stdClass $row) { |
|
25 | 162 | $this->initializeAttributes(); |
|
26 | |||
27 | 162 | foreach ((array) $row as $key => $value) { |
|
28 | 162 | $this->attributes[$key] = $value; |
|
29 | } |
||
30 | |||
31 | 162 | $this->attributes['id'] = (int) $this->attributes['id']; |
|
32 | 162 | } |
|
33 | |||
34 | /** |
||
35 | * (non-PHPdoc) |
||
36 | * |
||
37 | * @see \ElggData::initializeAttributes() |
||
38 | * |
||
39 | * @return void |
||
40 | */ |
||
41 | 162 | protected function initializeAttributes() { |
|
42 | 162 | parent::initializeAttributes(); |
|
43 | |||
44 | 162 | $this->attributes['id'] = null; |
|
45 | 162 | $this->attributes['guid_one'] = null; |
|
46 | 162 | $this->attributes['relationship'] = null; |
|
47 | 162 | $this->attributes['guid_two'] = null; |
|
48 | 162 | } |
|
49 | |||
50 | /** |
||
51 | * Set an attribute of the relationship |
||
52 | * |
||
53 | * @param string $name Name |
||
54 | * @param mixed $value Value |
||
55 | * @return void |
||
56 | */ |
||
57 | 1 | public function __set($name, $value) { |
|
58 | 1 | $this->attributes[$name] = $value; |
|
59 | 1 | } |
|
60 | |||
61 | /** |
||
62 | * Get an attribute of the relationship |
||
63 | * |
||
64 | * @param string $name Name |
||
65 | * @return mixed |
||
66 | */ |
||
67 | 42 | public function __get($name) { |
|
68 | 42 | if (array_key_exists($name, $this->attributes)) { |
|
69 | 42 | return $this->attributes[$name]; |
|
70 | } |
||
71 | |||
72 | 27 | return null; |
|
73 | } |
||
74 | |||
75 | /** |
||
76 | * Save the relationship |
||
77 | * |
||
78 | * @return int the relationship ID |
||
79 | * @throws IOException |
||
80 | */ |
||
81 | 1 | public function save() { |
|
82 | 1 | if ($this->id > 0) { |
|
83 | 1 | delete_relationship($this->id); |
|
84 | } |
||
85 | |||
86 | 1 | $this->id = _elgg_services()->relationshipsTable->add( |
|
0 ignored issues
–
show
|
|||
87 | 1 | $this->guid_one, |
|
88 | 1 | $this->relationship, |
|
89 | 1 | $this->guid_two, |
|
90 | 1 | true |
|
91 | ); |
||
92 | 1 | if (!$this->id) { |
|
93 | throw new \IOException("Unable to save new " . get_class()); |
||
94 | } |
||
95 | |||
96 | 1 | return $this->id; |
|
97 | } |
||
98 | |||
99 | /** |
||
100 | * Delete this relationship from the database. |
||
101 | * |
||
102 | * @return bool |
||
103 | */ |
||
104 | 2 | public function delete() { |
|
105 | 2 | return delete_relationship($this->id); |
|
106 | } |
||
107 | |||
108 | /** |
||
109 | * Get a URL for this relationship. |
||
110 | * |
||
111 | * Plugins can register for the 'relationship:url', 'relationship' plugin hook to |
||
112 | * customize the url for a relationship. |
||
113 | * |
||
114 | * @return string |
||
115 | */ |
||
116 | 3 | public function getURL() { |
|
117 | 3 | $url = ''; |
|
118 | // @todo remove when elgg_register_relationship_url_handler() has been removed |
||
119 | 3 | if ($this->id) { |
|
120 | 3 | $subtype = $this->getSubtype(); |
|
121 | |||
122 | 3 | $function = ""; |
|
123 | 3 | $handlers = _elgg_config()->relationship_url_handler; |
|
124 | |||
125 | 3 | if (isset($handlers[$subtype])) { |
|
126 | $function = $handlers[$subtype]; |
||
127 | } |
||
128 | 3 | if (isset($handlers['all'])) { |
|
129 | $function = $handlers['all']; |
||
130 | } |
||
131 | |||
132 | 3 | if (is_callable($function)) { |
|
133 | $url = call_user_func($function, $this); |
||
134 | } |
||
135 | |||
136 | 3 | if ($url) { |
|
137 | $url = elgg_normalize_url($url); |
||
138 | } |
||
139 | } |
||
140 | |||
141 | 3 | $type = $this->getType(); |
|
142 | 3 | $params = ['relationship' => $this]; |
|
143 | 3 | $url = _elgg_services()->hooks->trigger('relationship:url', $type, $params, $url); |
|
144 | |||
145 | 3 | return elgg_normalize_url($url); |
|
146 | } |
||
147 | |||
148 | /** |
||
149 | * {@inheritdoc} |
||
150 | */ |
||
151 | public function toObject() { |
||
152 | $object = new \stdClass(); |
||
153 | $object->id = $this->id; |
||
154 | $object->subject_guid = $this->guid_one; |
||
155 | $object->relationship = $this->relationship; |
||
156 | $object->object_guid = $this->guid_two; |
||
157 | $object->time_created = date('c', $this->getTimeCreated()); |
||
158 | $params = ['relationship' => $this]; |
||
159 | return _elgg_services()->hooks->trigger('to:object', 'relationship', $params, $object); |
||
160 | } |
||
161 | |||
162 | // SYSTEM LOG INTERFACE //////////////////////////////////////////////////////////// |
||
163 | |||
164 | /** |
||
165 | * Return an identification for the object for storage in the system log. |
||
166 | * This id must be an integer. |
||
167 | * |
||
168 | * @return int |
||
169 | */ |
||
170 | 25 | public function getSystemLogID() { |
|
171 | 25 | return $this->id; |
|
172 | } |
||
173 | |||
174 | /** |
||
175 | * For a given ID, return the object associated with it. |
||
176 | * This is used by the river functionality primarily. |
||
177 | * This is useful for checking access permissions etc on objects. |
||
178 | * |
||
179 | * @param int $id ID |
||
180 | * |
||
181 | * @return \ElggRelationship |
||
182 | */ |
||
183 | public function getObjectFromID($id) { |
||
184 | return get_relationship($id); |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * Return a type of the object - eg. object, group, user, relationship, metadata, annotation etc |
||
189 | * |
||
190 | * @return string 'relationship' |
||
191 | */ |
||
192 | 37 | public function getType() { |
|
193 | 37 | return 'relationship'; |
|
194 | } |
||
195 | |||
196 | /** |
||
197 | * Return a subtype. For metadata & annotations this is the 'name' and for relationship this |
||
198 | * is the relationship type. |
||
199 | * |
||
200 | * @return string |
||
201 | */ |
||
202 | 37 | public function getSubtype() { |
|
203 | 37 | return $this->relationship; |
|
204 | } |
||
205 | } |
||
206 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.