1 | <?php |
||||||
2 | |||||||
3 | use Elgg\EntityIcon; |
||||||
4 | |||||||
5 | /** |
||||||
6 | * The parent class for all Elgg Entities. |
||||||
7 | * |
||||||
8 | * An \ElggEntity is one of the basic data models in Elgg. |
||||||
9 | * It is the primary means of storing and retrieving data from the database. |
||||||
10 | * An \ElggEntity represents one row of the entities table. |
||||||
11 | * |
||||||
12 | * The \ElggEntity class handles CRUD operations for the entities table. |
||||||
13 | * \ElggEntity should always be extended by another class to handle CRUD |
||||||
14 | * operations on the type-specific table. |
||||||
15 | * |
||||||
16 | * \ElggEntity uses magic methods for get and set, so any property that isn't |
||||||
17 | * declared will be assumed to be metadata and written to the database |
||||||
18 | * as metadata on the object. All children classes must declare which |
||||||
19 | * properties are columns of the type table or they will be assumed |
||||||
20 | * to be metadata. See \ElggObject::initializeAttributes() for examples. |
||||||
21 | * |
||||||
22 | * Core supports 4 types of entities: \ElggObject, \ElggUser, \ElggGroup, and \ElggSite. |
||||||
23 | * |
||||||
24 | * @tip Plugin authors will want to extend the \ElggObject class, not this class. |
||||||
25 | * |
||||||
26 | * @package Elgg.Core |
||||||
27 | * @subpackage DataModel.Entities |
||||||
28 | * |
||||||
29 | * @property string $type object, user, group, or site (read-only after save) |
||||||
30 | * @property string $subtype Further clarifies the nature of the entity (this should not be read) |
||||||
31 | * @property-read int $guid The unique identifier for this entity (read only) |
||||||
32 | * @property int $owner_guid The GUID of the owner of this entity (usually the creator) |
||||||
33 | * @property int $container_guid The GUID of the entity containing this entity |
||||||
34 | * @property int $access_id Specifies the visibility level of this entity |
||||||
35 | * @property int $time_created A UNIX timestamp of when the entity was created |
||||||
36 | * @property-read int $time_updated A UNIX timestamp of when the entity was last updated (automatically updated on save) |
||||||
37 | * @property-read int $last_action A UNIX timestamp of when the entity was last acted upon |
||||||
38 | * @property string $enabled Is this entity enabled ('yes' or 'no') |
||||||
39 | * |
||||||
40 | * Metadata (the above are attributes) |
||||||
41 | * @property string $location A location of the entity |
||||||
42 | */ |
||||||
43 | abstract class ElggEntity extends \ElggData implements |
||||||
44 | Locatable, // Geocoding interface |
||||||
45 | EntityIcon // Icon interface |
||||||
46 | { |
||||||
47 | |||||||
48 | public static $primary_attr_names = [ |
||||||
49 | 'guid', |
||||||
50 | 'type', |
||||||
51 | 'subtype', |
||||||
52 | 'owner_guid', |
||||||
53 | 'container_guid', |
||||||
54 | 'access_id', |
||||||
55 | 'time_created', |
||||||
56 | 'time_updated', |
||||||
57 | 'last_action', |
||||||
58 | 'enabled', |
||||||
59 | ]; |
||||||
60 | |||||||
61 | protected static $integer_attr_names = [ |
||||||
62 | 'guid', |
||||||
63 | 'owner_guid', |
||||||
64 | 'container_guid', |
||||||
65 | 'access_id', |
||||||
66 | 'time_created', |
||||||
67 | 'time_updated', |
||||||
68 | 'last_action', |
||||||
69 | ]; |
||||||
70 | |||||||
71 | /** |
||||||
72 | * Holds metadata until entity is saved. Once the entity is saved, |
||||||
73 | * metadata are written immediately to the database. |
||||||
74 | * @var array |
||||||
75 | */ |
||||||
76 | protected $temp_metadata = []; |
||||||
77 | |||||||
78 | /** |
||||||
79 | * Holds annotations until entity is saved. Once the entity is saved, |
||||||
80 | * annotations are written immediately to the database. |
||||||
81 | * @var array |
||||||
82 | */ |
||||||
83 | protected $temp_annotations = []; |
||||||
84 | |||||||
85 | /** |
||||||
86 | * Holds private settings until entity is saved. Once the entity is saved, |
||||||
87 | * private settings are written immediately to the database. |
||||||
88 | * @var array |
||||||
89 | */ |
||||||
90 | protected $temp_private_settings = []; |
||||||
91 | |||||||
92 | /** |
||||||
93 | * Volatile data structure for this object, allows for storage of data |
||||||
94 | * in-memory that isn't sync'd back to the metadata table. |
||||||
95 | * @var array |
||||||
96 | */ |
||||||
97 | protected $volatile = []; |
||||||
98 | |||||||
99 | /** |
||||||
100 | * Holds the original (persisted) attribute values that have been changed but not yet saved. |
||||||
101 | * @var array |
||||||
102 | */ |
||||||
103 | protected $orig_attributes = []; |
||||||
104 | |||||||
105 | /** |
||||||
106 | * @var bool |
||||||
107 | */ |
||||||
108 | protected $_is_cacheable = true; |
||||||
109 | |||||||
110 | /** |
||||||
111 | * Create a new entity. |
||||||
112 | * |
||||||
113 | * Plugin developers should only use the constructor to create a new entity. |
||||||
114 | * To retrieve entities, use get_entity() and the elgg_get_entities* functions. |
||||||
115 | * |
||||||
116 | * If no arguments are passed, it creates a new entity. |
||||||
117 | * If a database result is passed as a \stdClass instance, it instantiates |
||||||
118 | * that entity. |
||||||
119 | * |
||||||
120 | * @param stdClass $row Database row result. Default is null to create a new object. |
||||||
121 | * |
||||||
122 | * @throws IOException If cannot load remaining data from db |
||||||
123 | */ |
||||||
124 | 5322 | public function __construct(stdClass $row = null) { |
|||||
125 | 5322 | $this->initializeAttributes(); |
|||||
126 | |||||||
127 | 5322 | if ($row && !$this->load($row)) { |
|||||
128 | $msg = "Failed to load new " . get_class() . " for GUID:" . $row->guid; |
||||||
129 | throw new \IOException($msg); |
||||||
130 | } |
||||||
131 | 5322 | } |
|||||
132 | |||||||
133 | /** |
||||||
134 | * Initialize the attributes array. |
||||||
135 | * |
||||||
136 | * This is vital to distinguish between metadata and base parameters. |
||||||
137 | * |
||||||
138 | * @return void |
||||||
139 | */ |
||||||
140 | 5322 | protected function initializeAttributes() { |
|||||
141 | 5322 | parent::initializeAttributes(); |
|||||
142 | |||||||
143 | 5322 | $this->attributes['guid'] = null; |
|||||
144 | 5322 | $this->attributes['type'] = null; |
|||||
145 | 5322 | $this->attributes['subtype'] = null; |
|||||
146 | |||||||
147 | 5322 | $this->attributes['owner_guid'] = _elgg_services()->session->getLoggedInUserGuid(); |
|||||
148 | 5322 | $this->attributes['container_guid'] = _elgg_services()->session->getLoggedInUserGuid(); |
|||||
149 | |||||||
150 | 5322 | $this->attributes['access_id'] = ACCESS_PRIVATE; |
|||||
151 | 5322 | $this->attributes['time_updated'] = null; |
|||||
152 | 5322 | $this->attributes['last_action'] = null; |
|||||
153 | 5322 | $this->attributes['enabled'] = "yes"; |
|||||
154 | |||||||
155 | 5322 | $this->attributes['type'] = $this->getType(); |
|||||
156 | 5322 | } |
|||||
157 | |||||||
158 | /** |
||||||
159 | * Clone an entity |
||||||
160 | * |
||||||
161 | * Resets the guid so that the entity can be saved as a distinct entity from |
||||||
162 | * the original. Creation time will be set when this new entity is saved. |
||||||
163 | * The owner and container guids come from the original entity. The clone |
||||||
164 | * method copies metadata but does not copy annotations or private settings. |
||||||
165 | * |
||||||
166 | * @note metadata will have its owner and access id set when the entity is saved |
||||||
167 | * and it will be the same as that of the entity. |
||||||
168 | * |
||||||
169 | * @return void |
||||||
170 | */ |
||||||
171 | 1 | public function __clone() { |
|||||
172 | 1 | $orig_entity = get_entity($this->guid); |
|||||
173 | 1 | if (!$orig_entity) { |
|||||
174 | _elgg_services()->logger->error("Failed to clone entity with GUID $this->guid"); |
||||||
175 | return; |
||||||
176 | } |
||||||
177 | |||||||
178 | 1 | $metadata_array = elgg_get_metadata([ |
|||||
179 | 1 | 'guid' => $this->guid, |
|||||
180 | 1 | 'limit' => 0 |
|||||
181 | ]); |
||||||
182 | |||||||
183 | 1 | $this->attributes['guid'] = null; |
|||||
184 | 1 | $this->attributes['time_created'] = null; |
|||||
185 | 1 | $this->attributes['time_updated'] = null; |
|||||
186 | 1 | $this->attributes['last_action'] = null; |
|||||
187 | |||||||
188 | 1 | $this->attributes['subtype'] = $orig_entity->getSubtype(); |
|||||
189 | |||||||
190 | // copy metadata over to new entity - slightly convoluted due to |
||||||
191 | // handling of metadata arrays |
||||||
192 | 1 | if (is_array($metadata_array)) { |
|||||
193 | // create list of metadata names |
||||||
194 | 1 | $metadata_names = []; |
|||||
195 | 1 | foreach ($metadata_array as $metadata) { |
|||||
196 | 1 | $metadata_names[] = $metadata['name']; |
|||||
197 | } |
||||||
198 | // arrays are stored with multiple enties per name |
||||||
199 | 1 | $metadata_names = array_unique($metadata_names); |
|||||
200 | |||||||
201 | // move the metadata over |
||||||
202 | 1 | foreach ($metadata_names as $name) { |
|||||
203 | 1 | $this->__set($name, $orig_entity->$name); |
|||||
204 | } |
||||||
205 | } |
||||||
206 | 1 | } |
|||||
207 | |||||||
208 | /** |
||||||
209 | * Set an attribute or metadata value for this entity |
||||||
210 | * |
||||||
211 | * Anything that is not an attribute is saved as metadata. |
||||||
212 | * |
||||||
213 | * @warning Metadata set this way will inherit the entity's owner and |
||||||
214 | * access ID. If you want more control over metadata, use \ElggEntity::setMetadata() |
||||||
215 | * |
||||||
216 | * @param string $name Name of the attribute or metadata |
||||||
217 | * @param mixed $value The value to be set |
||||||
218 | * @return void |
||||||
219 | * @see \ElggEntity::setMetadata() |
||||||
220 | */ |
||||||
221 | 1092 | public function __set($name, $value) { |
|||||
222 | 1092 | if ($this->$name === $value) { |
|||||
223 | // quick return if value is not changing |
||||||
224 | 289 | return; |
|||||
225 | } |
||||||
226 | |||||||
227 | // Due to https://github.com/Elgg/Elgg/pull/5456#issuecomment-17785173, certain attributes |
||||||
228 | // will store empty strings as null in the DB. In the somewhat common case that we're re-setting |
||||||
229 | // the value to empty string, don't consider this a change. |
||||||
230 | 1092 | if (in_array($name, ['title', 'name', 'description']) |
|||||
231 | 1092 | && $this->$name === null |
|||||
232 | 1092 | && $value === "") { |
|||||
233 | return; |
||||||
234 | } |
||||||
235 | |||||||
236 | 1092 | if (array_key_exists($name, $this->attributes)) { |
|||||
237 | // if an attribute is 1 (integer) and it's set to "1" (string), don't consider that a change. |
||||||
238 | 589 | if (is_int($this->attributes[$name]) |
|||||
239 | 589 | && is_string($value) |
|||||
240 | 589 | && ((string) $this->attributes[$name] === $value)) { |
|||||
241 | 1 | return; |
|||||
242 | } |
||||||
243 | |||||||
244 | // keep original values |
||||||
245 | 589 | if ($this->guid && !array_key_exists($name, $this->orig_attributes)) { |
|||||
246 | 9 | $this->orig_attributes[$name] = $this->attributes[$name]; |
|||||
247 | } |
||||||
248 | |||||||
249 | // Certain properties should not be manually changed! |
||||||
250 | 589 | switch ($name) { |
|||||
251 | case 'guid': |
||||||
252 | case 'time_updated': |
||||||
253 | case 'last_action': |
||||||
254 | return; |
||||||
255 | break; |
||||||
256 | case 'access_id': |
||||||
257 | case 'owner_guid': |
||||||
258 | case 'container_guid': |
||||||
259 | 482 | if ($value !== null) { |
|||||
260 | 482 | $this->attributes[$name] = (int) $value; |
|||||
261 | } else { |
||||||
262 | $this->attributes[$name] = null; |
||||||
263 | } |
||||||
264 | 482 | break; |
|||||
265 | default: |
||||||
266 | 443 | $this->attributes[$name] = $value; |
|||||
267 | 443 | break; |
|||||
268 | } |
||||||
269 | 589 | return; |
|||||
270 | } |
||||||
271 | |||||||
272 | 1062 | $this->setMetadata($name, $value); |
|||||
273 | 1062 | } |
|||||
274 | |||||||
275 | /** |
||||||
276 | * Get the original values of attribute(s) that have been modified since the entity was persisted. |
||||||
277 | * |
||||||
278 | * @return array |
||||||
279 | */ |
||||||
280 | 59 | public function getOriginalAttributes() { |
|||||
281 | 59 | return $this->orig_attributes; |
|||||
282 | } |
||||||
283 | |||||||
284 | /** |
||||||
285 | * Get an attribute or metadata value |
||||||
286 | * |
||||||
287 | * If the name matches an attribute, the attribute is returned. If metadata |
||||||
288 | * does not exist with that name, a null is returned. |
||||||
289 | * |
||||||
290 | * This only returns an array if there are multiple values for a particular |
||||||
291 | * $name key. |
||||||
292 | * |
||||||
293 | * @param string $name Name of the attribute or metadata |
||||||
294 | * @return mixed |
||||||
295 | */ |
||||||
296 | 5387 | public function __get($name) { |
|||||
297 | 5387 | if (array_key_exists($name, $this->attributes)) { |
|||||
298 | 5386 | return $this->attributes[$name]; |
|||||
299 | } |
||||||
300 | |||||||
301 | 5363 | return $this->getMetadata($name); |
|||||
302 | } |
||||||
303 | |||||||
304 | /** |
||||||
305 | * Get the entity's display name |
||||||
306 | * |
||||||
307 | * @return string The title or name of this entity. |
||||||
308 | */ |
||||||
309 | 19 | public function getDisplayName() { |
|||||
310 | 19 | return $this->name; |
|||||
311 | } |
||||||
312 | |||||||
313 | /** |
||||||
314 | * Sets the title or name of this entity. |
||||||
315 | * |
||||||
316 | * @param string $display_name The title or name of this entity. |
||||||
317 | * @return void |
||||||
318 | */ |
||||||
319 | public function setDisplayName($display_name) { |
||||||
320 | $this->name = $display_name; |
||||||
1 ignored issue
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||||||
321 | } |
||||||
322 | |||||||
323 | /** |
||||||
324 | * Return the value of a piece of metadata. |
||||||
325 | * |
||||||
326 | * @param string $name Name |
||||||
327 | * |
||||||
328 | * @return mixed The value, or null if not found. |
||||||
329 | */ |
||||||
330 | 5363 | public function getMetadata($name) { |
|||||
331 | 5363 | $guid = $this->guid; |
|||||
332 | |||||||
333 | 5363 | if (!$guid) { |
|||||
334 | 572 | if (isset($this->temp_metadata[$name])) { |
|||||
335 | // md is returned as an array only if more than 1 entry |
||||||
336 | 285 | if (count($this->temp_metadata[$name]) == 1) { |
|||||
337 | 285 | return $this->temp_metadata[$name][0]; |
|||||
338 | } else { |
||||||
339 | 158 | return $this->temp_metadata[$name]; |
|||||
340 | } |
||||||
341 | } else { |
||||||
342 | 572 | return null; |
|||||
343 | } |
||||||
344 | } |
||||||
345 | |||||||
346 | // upon first cache miss, just load/cache all the metadata and retry. |
||||||
347 | // if this works, the rest of this function may not be needed! |
||||||
348 | 5354 | $cache = _elgg_services()->metadataCache; |
|||||
349 | 5354 | if ($cache->isLoaded($guid)) { |
|||||
350 | 2238 | return $cache->getSingle($guid, $name); |
|||||
351 | } else { |
||||||
352 | 4136 | $cache->populateFromEntities([$guid]); |
|||||
353 | // in case ignore_access was on, we have to check again... |
||||||
354 | 4136 | if ($cache->isLoaded($guid)) { |
|||||
355 | 1082 | return $cache->getSingle($guid, $name); |
|||||
356 | } |
||||||
357 | } |
||||||
358 | |||||||
359 | 4083 | $md = elgg_get_metadata([ |
|||||
360 | 4083 | 'guid' => $guid, |
|||||
361 | 4083 | 'metadata_name' => $name, |
|||||
362 | 4083 | 'limit' => 0, |
|||||
363 | 'distinct' => false, |
||||||
364 | ]); |
||||||
365 | |||||||
366 | 4083 | $value = null; |
|||||
367 | |||||||
368 | 4083 | if ($md && !is_array($md)) { |
|||||
369 | $value = $md->value; |
||||||
0 ignored issues
–
show
|
|||||||
370 | 4083 | } elseif (count($md) == 1) { |
|||||
371 | $value = $md[0]->value; |
||||||
372 | 4083 | } else if ($md && is_array($md)) { |
|||||
373 | $value = metadata_array_to_values($md); |
||||||
374 | } |
||||||
375 | |||||||
376 | 4083 | return $value; |
|||||
377 | } |
||||||
378 | |||||||
379 | /** |
||||||
380 | * Unset a property from metadata or attribute. |
||||||
381 | * |
||||||
382 | * @warning If you use this to unset an attribute, you must save the object! |
||||||
383 | * |
||||||
384 | * @param string $name The name of the attribute or metadata. |
||||||
385 | * |
||||||
386 | * @return void |
||||||
387 | * @todo some attributes should be set to null or other default values |
||||||
388 | */ |
||||||
389 | 49 | public function __unset($name) { |
|||||
390 | 49 | if (array_key_exists($name, $this->attributes)) { |
|||||
391 | $this->attributes[$name] = ""; |
||||||
392 | } else { |
||||||
393 | 49 | $this->deleteMetadata($name); |
|||||
394 | } |
||||||
395 | 49 | } |
|||||
396 | |||||||
397 | /** |
||||||
398 | * Set metadata on this entity. |
||||||
399 | * |
||||||
400 | * Plugin developers usually want to use the magic set method ($entity->name = 'value'). |
||||||
401 | * Use this method if you want to explicitly set the owner or access of the metadata. |
||||||
402 | * You cannot set the owner/access before the entity has been saved. |
||||||
403 | * |
||||||
404 | * @param string $name Name of the metadata |
||||||
405 | * @param mixed $value Value of the metadata (doesn't support assoc arrays) |
||||||
406 | * @param string $value_type 'text', 'integer', or '' for automatic detection |
||||||
407 | * @param bool $multiple Allow multiple values for a single name. |
||||||
408 | * Does not support associative arrays. |
||||||
409 | * |
||||||
410 | * @return bool |
||||||
411 | * @throws InvalidArgumentException |
||||||
412 | */ |
||||||
413 | 1062 | public function setMetadata($name, $value, $value_type = '', $multiple = false) { |
|||||
414 | |||||||
415 | // normalize value to an array that we will loop over |
||||||
416 | // remove indexes if value already an array. |
||||||
417 | 1062 | if (is_array($value)) { |
|||||
418 | 162 | $value = array_values($value); |
|||||
419 | } else { |
||||||
420 | 1061 | $value = [$value]; |
|||||
421 | } |
||||||
422 | |||||||
423 | // strip null values from array |
||||||
424 | 1062 | $value = array_filter($value, function($var) { |
|||||
425 | 1062 | return !is_null($var); |
|||||
426 | 1062 | }); |
|||||
427 | |||||||
428 | 1062 | if (empty($this->guid)) { |
|||||
429 | // unsaved entity. store in temp array |
||||||
430 | 569 | return $this->setTempMetadata($name, $value, $multiple); |
|||||
431 | } |
||||||
432 | |||||||
433 | // saved entity. persist md to db. |
||||||
434 | 1028 | if (!$multiple) { |
|||||
435 | 1028 | $current_metadata = $this->getMetadata($name); |
|||||
436 | |||||||
437 | 1028 | if ((is_array($current_metadata) || count($value) > 1 || $value === []) && isset($current_metadata)) { |
|||||
438 | // remove current metadata if needed |
||||||
439 | // need to remove access restrictions right now to delete |
||||||
440 | // because this is the expected behavior |
||||||
441 | 8 | $ia = elgg_set_ignore_access(true); |
|||||
442 | 8 | $delete_result = elgg_delete_metadata([ |
|||||
443 | 8 | 'guid' => $this->guid, |
|||||
444 | 8 | 'metadata_name' => $name, |
|||||
445 | 'limit' => false, |
||||||
446 | ]); |
||||||
447 | 8 | elgg_set_ignore_access($ia); |
|||||
448 | |||||||
449 | 8 | if (false === $delete_result) { |
|||||
450 | return false; |
||||||
451 | } |
||||||
452 | } |
||||||
453 | |||||||
454 | 1028 | if (count($value) > 1) { |
|||||
455 | // new value is a multiple valued metadata |
||||||
456 | 162 | $multiple = true; |
|||||
457 | } |
||||||
458 | } |
||||||
459 | |||||||
460 | // create new metadata |
||||||
461 | 1028 | foreach ($value as $value_tmp) { |
|||||
462 | 1028 | $metadata = new ElggMetadata(); |
|||||
463 | 1028 | $metadata->entity_guid = $this->guid; |
|||||
464 | 1028 | $metadata->name = $name; |
|||||
465 | 1028 | $metadata->value_type = $value_type; |
|||||
466 | 1028 | $metadata->value = $value_tmp; |
|||||
467 | 1028 | $md_id = _elgg_services()->metadataTable->create($metadata, $multiple); |
|||||
468 | 1028 | if (!$md_id) { |
|||||
469 | 1028 | return false; |
|||||
470 | } |
||||||
471 | } |
||||||
472 | |||||||
473 | 1028 | return true; |
|||||
474 | } |
||||||
475 | |||||||
476 | /** |
||||||
477 | * Set temp metadata on this entity. |
||||||
478 | * |
||||||
479 | * @param string $name Name of the metadata |
||||||
480 | * @param mixed $value Value of the metadata (doesn't support assoc arrays) |
||||||
481 | * @param bool $multiple Allow multiple values for a single name. |
||||||
482 | * Does not support associative arrays. |
||||||
483 | * |
||||||
484 | * @return bool |
||||||
485 | */ |
||||||
486 | 569 | protected function setTempMetadata($name, $value, $multiple = false) { |
|||||
487 | // if overwrite, delete first |
||||||
488 | 569 | if (!$multiple) { |
|||||
489 | 569 | unset($this->temp_metadata[$name]); |
|||||
490 | 569 | if (count($value)) { |
|||||
491 | // only save if value array contains data |
||||||
492 | 569 | $this->temp_metadata[$name] = $value; |
|||||
493 | } |
||||||
494 | 569 | return true; |
|||||
495 | } |
||||||
496 | |||||||
497 | 3 | if (!isset($this->temp_metadata[$name])) { |
|||||
498 | $this->temp_metadata[$name] = []; |
||||||
499 | } |
||||||
500 | |||||||
501 | 3 | $this->temp_metadata[$name] = array_merge($this->temp_metadata[$name], $value); |
|||||
502 | |||||||
503 | 3 | return true; |
|||||
504 | } |
||||||
505 | |||||||
506 | |||||||
507 | |||||||
508 | /** |
||||||
509 | * Deletes all metadata on this object (metadata.entity_guid = $this->guid). |
||||||
510 | * If you pass a name, only metadata matching that name will be deleted. |
||||||
511 | * |
||||||
512 | * @warning Calling this with no $name will clear all metadata on the entity. |
||||||
513 | * |
||||||
514 | * @param null|string $name The name of the metadata to remove. |
||||||
515 | * @return bool|null |
||||||
516 | * @since 1.8 |
||||||
517 | */ |
||||||
518 | 266 | public function deleteMetadata($name = null) { |
|||||
519 | |||||||
520 | 266 | if (!$this->guid) { |
|||||
521 | // remove from temp_metadata |
||||||
522 | 2 | if ($name) { |
|||||
0 ignored issues
–
show
The expression
$name of type null|string is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||||||
523 | 2 | if (!isset($this->temp_metadata[$name])) { |
|||||
524 | return null; |
||||||
525 | } else { |
||||||
526 | 2 | unset($this->temp_metadata[$name]); |
|||||
527 | 2 | return true; |
|||||
528 | } |
||||||
529 | } else { |
||||||
530 | $this->temp_metadata = []; |
||||||
531 | return true; |
||||||
532 | } |
||||||
533 | } |
||||||
534 | |||||||
535 | $options = [ |
||||||
536 | 266 | 'guid' => $this->guid, |
|||||
537 | 266 | 'limit' => 0 |
|||||
538 | ]; |
||||||
539 | 266 | if ($name) { |
|||||
0 ignored issues
–
show
The expression
$name of type null|string is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||||||
540 | 55 | $options['metadata_name'] = $name; |
|||||
541 | } |
||||||
542 | |||||||
543 | 266 | return elgg_delete_metadata($options); |
|||||
544 | } |
||||||
545 | |||||||
546 | /** |
||||||
547 | * Get a piece of volatile (non-persisted) data on this entity. |
||||||
548 | * |
||||||
549 | * @param string $name The name of the volatile data |
||||||
550 | * |
||||||
551 | * @return mixed The value or null if not found. |
||||||
552 | */ |
||||||
553 | 25 | public function getVolatileData($name) { |
|||||
554 | 25 | return array_key_exists($name, $this->volatile) ? $this->volatile[$name] : null; |
|||||
555 | } |
||||||
556 | |||||||
557 | /** |
||||||
558 | * Set a piece of volatile (non-persisted) data on this entity |
||||||
559 | * |
||||||
560 | * @param string $name Name |
||||||
561 | * @param mixed $value Value |
||||||
562 | * |
||||||
563 | * @return void |
||||||
564 | */ |
||||||
565 | 26 | public function setVolatileData($name, $value) { |
|||||
566 | 26 | $this->volatile[$name] = $value; |
|||||
567 | 26 | } |
|||||
568 | |||||||
569 | /** |
||||||
570 | * Remove all relationships to and from this entity. |
||||||
571 | * If you pass a relationship name, only relationships matching that name |
||||||
572 | * will be deleted. |
||||||
573 | * |
||||||
574 | * @warning Calling this with no $relationship will clear all relationships |
||||||
575 | * for this entity. |
||||||
576 | * |
||||||
577 | * @param null|string $relationship The name of the relationship to remove. |
||||||
578 | * @return bool |
||||||
579 | * @see \ElggEntity::addRelationship() |
||||||
580 | * @see \ElggEntity::removeRelationship() |
||||||
581 | */ |
||||||
582 | 214 | public function deleteRelationships($relationship = null) { |
|||||
583 | 214 | $relationship = (string) $relationship; |
|||||
584 | 214 | $result = remove_entity_relationships($this->getGUID(), $relationship); |
|||||
585 | 214 | return $result && remove_entity_relationships($this->getGUID(), $relationship, true); |
|||||
586 | } |
||||||
587 | |||||||
588 | /** |
||||||
589 | * Add a relationship between this an another entity. |
||||||
590 | * |
||||||
591 | * @tip Read the relationship like "This entity is a $relationship of $guid_two." |
||||||
592 | * |
||||||
593 | * @param int $guid_two GUID of the target entity of the relationship. |
||||||
594 | * @param string $relationship The type of relationship. |
||||||
595 | * |
||||||
596 | * @return bool |
||||||
597 | * @see \ElggEntity::removeRelationship() |
||||||
598 | * @see \ElggEntity::deleteRelationships() |
||||||
599 | */ |
||||||
600 | 5 | public function addRelationship($guid_two, $relationship) { |
|||||
601 | 5 | return add_entity_relationship($this->getGUID(), $relationship, $guid_two); |
|||||
602 | } |
||||||
603 | |||||||
604 | /** |
||||||
605 | * Remove a relationship |
||||||
606 | * |
||||||
607 | * @param int $guid_two GUID of the target entity of the relationship. |
||||||
608 | * @param string $relationship The type of relationship. |
||||||
609 | * |
||||||
610 | * @return bool |
||||||
611 | * @see \ElggEntity::addRelationship() |
||||||
612 | * @see \ElggEntity::deleteRelationships() |
||||||
613 | */ |
||||||
614 | 1 | public function removeRelationship($guid_two, $relationship) { |
|||||
615 | 1 | return remove_entity_relationship($this->getGUID(), $relationship, $guid_two); |
|||||
616 | } |
||||||
617 | |||||||
618 | /** |
||||||
619 | * Adds a private setting to this entity. |
||||||
620 | * |
||||||
621 | * Private settings are similar to metadata but will not |
||||||
622 | * be searched and there are fewer helper functions for them. |
||||||
623 | * |
||||||
624 | * @param string $name Name of private setting |
||||||
625 | * @param mixed $value Value of private setting |
||||||
626 | * |
||||||
627 | * @return bool |
||||||
628 | */ |
||||||
629 | 124 | public function setPrivateSetting($name, $value) { |
|||||
630 | 124 | if ((int) $this->guid > 0) { |
|||||
631 | 123 | return set_private_setting($this->getGUID(), $name, $value); |
|||||
632 | } else { |
||||||
633 | 45 | $this->temp_private_settings[$name] = $value; |
|||||
634 | 45 | return true; |
|||||
635 | } |
||||||
636 | } |
||||||
637 | |||||||
638 | /** |
||||||
639 | * Returns a private setting value |
||||||
640 | * |
||||||
641 | * @param string $name Name of the private setting |
||||||
642 | * |
||||||
643 | * @return mixed Null if the setting does not exist |
||||||
644 | */ |
||||||
645 | 37 | public function getPrivateSetting($name) { |
|||||
646 | 37 | if ((int) ($this->guid) > 0) { |
|||||
647 | 37 | return get_private_setting($this->getGUID(), $name); |
|||||
648 | } else { |
||||||
649 | 5 | if (isset($this->temp_private_settings[$name])) { |
|||||
650 | 5 | return $this->temp_private_settings[$name]; |
|||||
651 | } |
||||||
652 | } |
||||||
653 | 5 | return null; |
|||||
654 | } |
||||||
655 | |||||||
656 | /** |
||||||
657 | * Removes private setting |
||||||
658 | * |
||||||
659 | * @param string $name Name of the private setting |
||||||
660 | * |
||||||
661 | * @return bool |
||||||
662 | */ |
||||||
663 | 3 | public function removePrivateSetting($name) { |
|||||
664 | 3 | return remove_private_setting($this->getGUID(), $name); |
|||||
665 | } |
||||||
666 | |||||||
667 | /** |
||||||
668 | * Deletes all annotations on this object (annotations.entity_guid = $this->guid). |
||||||
669 | * If you pass a name, only annotations matching that name will be deleted. |
||||||
670 | * |
||||||
671 | * @warning Calling this with no or empty arguments will clear all annotations on the entity. |
||||||
672 | * |
||||||
673 | * @param null|string $name The annotations name to remove. |
||||||
674 | * @return bool |
||||||
675 | * @since 1.8 |
||||||
676 | */ |
||||||
677 | 214 | public function deleteAnnotations($name = null) { |
|||||
678 | $options = [ |
||||||
679 | 214 | 'guid' => $this->guid, |
|||||
680 | 214 | 'limit' => 0 |
|||||
681 | ]; |
||||||
682 | 214 | if ($name) { |
|||||
0 ignored issues
–
show
The expression
$name of type null|string is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||||||
683 | 1 | $options['annotation_name'] = $name; |
|||||
684 | } |
||||||
685 | |||||||
686 | 214 | return elgg_delete_annotations($options); |
|||||
687 | } |
||||||
688 | |||||||
689 | /** |
||||||
690 | * Deletes all annotations owned by this object (annotations.owner_guid = $this->guid). |
||||||
691 | * If you pass a name, only annotations matching that name will be deleted. |
||||||
692 | * |
||||||
693 | * @param null|string $name The name of annotations to delete. |
||||||
694 | * @return bool |
||||||
695 | * @since 1.8 |
||||||
696 | */ |
||||||
697 | 214 | public function deleteOwnedAnnotations($name = null) { |
|||||
698 | // access is turned off for this because they might |
||||||
699 | // no longer have access to an entity they created annotations on. |
||||||
700 | 214 | $ia = elgg_set_ignore_access(true); |
|||||
701 | $options = [ |
||||||
702 | 214 | 'annotation_owner_guid' => $this->guid, |
|||||
703 | 214 | 'limit' => 0 |
|||||
704 | ]; |
||||||
705 | 214 | if ($name) { |
|||||
0 ignored issues
–
show
The expression
$name of type null|string is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||||||
706 | $options['annotation_name'] = $name; |
||||||
707 | } |
||||||
708 | |||||||
709 | 214 | $r = elgg_delete_annotations($options); |
|||||
710 | 214 | elgg_set_ignore_access($ia); |
|||||
711 | 214 | return $r; |
|||||
712 | } |
||||||
713 | |||||||
714 | /** |
||||||
715 | * Disables annotations for this entity, optionally based on name. |
||||||
716 | * |
||||||
717 | * @param string $name An options name of annotations to disable. |
||||||
718 | * @return bool |
||||||
719 | * @since 1.8 |
||||||
720 | */ |
||||||
721 | 5 | public function disableAnnotations($name = '') { |
|||||
722 | $options = [ |
||||||
723 | 5 | 'guid' => $this->guid, |
|||||
724 | 5 | 'limit' => 0 |
|||||
725 | ]; |
||||||
726 | 5 | if ($name) { |
|||||
727 | $options['annotation_name'] = $name; |
||||||
728 | } |
||||||
729 | |||||||
730 | 5 | return elgg_disable_annotations($options); |
|||||
731 | } |
||||||
732 | |||||||
733 | /** |
||||||
734 | * Enables annotations for this entity, optionally based on name. |
||||||
735 | * |
||||||
736 | * @warning Before calling this, you must use {@link access_show_hidden_entities()} |
||||||
737 | * |
||||||
738 | * @param string $name An options name of annotations to enable. |
||||||
739 | * @return bool |
||||||
740 | * @since 1.8 |
||||||
741 | */ |
||||||
742 | 3 | public function enableAnnotations($name = '') { |
|||||
743 | $options = [ |
||||||
744 | 3 | 'guid' => $this->guid, |
|||||
745 | 3 | 'limit' => 0 |
|||||
746 | ]; |
||||||
747 | 3 | if ($name) { |
|||||
748 | $options['annotation_name'] = $name; |
||||||
749 | } |
||||||
750 | |||||||
751 | 3 | return elgg_enable_annotations($options); |
|||||
752 | } |
||||||
753 | |||||||
754 | /** |
||||||
755 | * Helper function to return annotation calculation results |
||||||
756 | * |
||||||
757 | * @param string $name The annotation name. |
||||||
758 | * @param string $calculation A valid MySQL function to run its values through |
||||||
759 | * @return mixed |
||||||
760 | */ |
||||||
761 | 2 | private function getAnnotationCalculation($name, $calculation) { |
|||||
762 | $options = [ |
||||||
763 | 2 | 'guid' => $this->getGUID(), |
|||||
764 | 'distinct' => false, |
||||||
765 | 2 | 'annotation_name' => $name, |
|||||
766 | 2 | 'annotation_calculation' => $calculation |
|||||
767 | ]; |
||||||
768 | |||||||
769 | 2 | return elgg_get_annotations($options); |
|||||
770 | } |
||||||
771 | |||||||
772 | /** |
||||||
773 | * Adds an annotation to an entity. |
||||||
774 | * |
||||||
775 | * @warning By default, annotations are private. |
||||||
776 | * |
||||||
777 | * @warning Annotating an unsaved entity more than once with the same name |
||||||
778 | * will only save the last annotation. |
||||||
779 | * |
||||||
780 | * @todo Update temp_annotations to store an instance of ElggAnnotation and simply call ElggAnnotation::save(), |
||||||
781 | * after entity is saved |
||||||
782 | * |
||||||
783 | * @param string $name Annotation name |
||||||
784 | * @param mixed $value Annotation value |
||||||
785 | * @param int $access_id Access ID |
||||||
786 | * @param int $owner_guid GUID of the annotation owner |
||||||
787 | * @param string $value_type The type of annotation value |
||||||
788 | * |
||||||
789 | * @return bool|int Returns int if an annotation is saved |
||||||
790 | */ |
||||||
791 | 93 | public function annotate($name, $value, $access_id = ACCESS_PRIVATE, $owner_guid = 0, $value_type = "") { |
|||||
792 | 93 | if ($this->guid) { |
|||||
793 | 93 | if (!$owner_guid) { |
|||||
794 | 92 | $owner_guid = elgg_get_logged_in_user_guid(); |
|||||
795 | } |
||||||
796 | 93 | $annotation = new ElggAnnotation(); |
|||||
797 | 93 | $annotation->entity_guid = $this->guid; |
|||||
798 | 93 | $annotation->name = $name; |
|||||
799 | 93 | $annotation->value_type = $value_type; |
|||||
800 | 93 | $annotation->value = $value; |
|||||
801 | 93 | $annotation->owner_guid = $owner_guid; |
|||||
802 | 93 | $annotation->access_id = $access_id; |
|||||
803 | 93 | return $annotation->save(); |
|||||
804 | } else { |
||||||
805 | 17 | $this->temp_annotations[$name] = $value; |
|||||
806 | } |
||||||
807 | 17 | return true; |
|||||
808 | } |
||||||
809 | |||||||
810 | /** |
||||||
811 | * Gets an array of annotations. |
||||||
812 | * |
||||||
813 | * To retrieve annotations on an unsaved entity, pass array('name' => [annotation name]) |
||||||
814 | * as the options array. |
||||||
815 | * |
||||||
816 | * @param array $options Array of options for elgg_get_annotations() except guid. |
||||||
817 | * |
||||||
818 | * @return array |
||||||
819 | * @see elgg_get_annotations() |
||||||
820 | */ |
||||||
821 | 9 | public function getAnnotations(array $options = []) { |
|||||
822 | 9 | if ($this->guid) { |
|||||
823 | 9 | $options['guid'] = $this->guid; |
|||||
824 | |||||||
825 | 9 | return elgg_get_annotations($options); |
|||||
0 ignored issues
–
show
|
|||||||
826 | } else { |
||||||
827 | $name = elgg_extract('annotation_name', $options, ''); |
||||||
828 | |||||||
829 | if (isset($this->temp_annotations[$name])) { |
||||||
830 | return [$this->temp_annotations[$name]]; |
||||||
831 | } |
||||||
832 | } |
||||||
833 | |||||||
834 | return []; |
||||||
835 | } |
||||||
836 | |||||||
837 | /** |
||||||
838 | * Count annotations. |
||||||
839 | * |
||||||
840 | * @param string $name The type of annotation. |
||||||
841 | * |
||||||
842 | * @return int |
||||||
843 | */ |
||||||
844 | 2 | public function countAnnotations($name = "") { |
|||||
845 | 2 | return $this->getAnnotationCalculation($name, 'count'); |
|||||
0 ignored issues
–
show
|
|||||||
846 | } |
||||||
847 | |||||||
848 | /** |
||||||
849 | * Get the average of an integer type annotation. |
||||||
850 | * |
||||||
851 | * @param string $name Annotation name |
||||||
852 | * |
||||||
853 | * @return int |
||||||
854 | */ |
||||||
855 | public function getAnnotationsAvg($name) { |
||||||
856 | return $this->getAnnotationCalculation($name, 'avg'); |
||||||
0 ignored issues
–
show
|
|||||||
857 | } |
||||||
858 | |||||||
859 | /** |
||||||
860 | * Get the sum of integer type annotations of a given name. |
||||||
861 | * |
||||||
862 | * @param string $name Annotation name |
||||||
863 | * |
||||||
864 | * @return int |
||||||
865 | */ |
||||||
866 | public function getAnnotationsSum($name) { |
||||||
867 | return $this->getAnnotationCalculation($name, 'sum'); |
||||||
0 ignored issues
–
show
|
|||||||
868 | } |
||||||
869 | |||||||
870 | /** |
||||||
871 | * Get the minimum of integer type annotations of given name. |
||||||
872 | * |
||||||
873 | * @param string $name Annotation name |
||||||
874 | * |
||||||
875 | * @return int |
||||||
876 | */ |
||||||
877 | public function getAnnotationsMin($name) { |
||||||
878 | return $this->getAnnotationCalculation($name, 'min'); |
||||||
0 ignored issues
–
show
|
|||||||
879 | } |
||||||
880 | |||||||
881 | /** |
||||||
882 | * Get the maximum of integer type annotations of a given name. |
||||||
883 | * |
||||||
884 | * @param string $name Annotation name |
||||||
885 | * |
||||||
886 | * @return int |
||||||
887 | */ |
||||||
888 | public function getAnnotationsMax($name) { |
||||||
889 | return $this->getAnnotationCalculation($name, 'max'); |
||||||
0 ignored issues
–
show
|
|||||||
890 | } |
||||||
891 | |||||||
892 | /** |
||||||
893 | * Count the number of comments attached to this entity. |
||||||
894 | * |
||||||
895 | * @return int Number of comments |
||||||
896 | * @since 1.8.0 |
||||||
897 | */ |
||||||
898 | 2 | public function countComments() { |
|||||
899 | 2 | $params = ['entity' => $this]; |
|||||
900 | 2 | $num = _elgg_services()->hooks->trigger('comments:count', $this->getType(), $params); |
|||||
901 | |||||||
902 | 2 | if (is_int($num)) { |
|||||
903 | return $num; |
||||||
904 | } |
||||||
905 | |||||||
906 | 2 | return elgg_get_entities([ |
|||||
1 ignored issue
–
show
|
|||||||
907 | 2 | 'type' => 'object', |
|||||
908 | 2 | 'subtype' => 'comment', |
|||||
909 | 2 | 'container_guid' => $this->getGUID(), |
|||||
910 | 'count' => true, |
||||||
911 | 'distinct' => false, |
||||||
912 | ]); |
||||||
913 | } |
||||||
914 | |||||||
915 | /** |
||||||
916 | * Returns the ACLs owned by the entity |
||||||
917 | * |
||||||
918 | * @param array $options additional options to get the access collections with |
||||||
919 | * |
||||||
920 | * @return \ElggAccessCollection[] |
||||||
921 | * |
||||||
922 | * @see elgg_get_access_collections() |
||||||
923 | * @since 3.0 |
||||||
924 | */ |
||||||
925 | 218 | public function getOwnedAccessCollections($options = []) { |
|||||
926 | 218 | $options['owner_guid'] = $this->guid; |
|||||
927 | 218 | return _elgg_services()->accessCollections->getEntityCollections($options); |
|||||
928 | } |
||||||
929 | |||||||
930 | /** |
||||||
931 | * Returns the first ACL owned by the entity with a given subtype |
||||||
932 | * |
||||||
933 | * @param string $subtype subtype of the ACL |
||||||
934 | * |
||||||
935 | * @return \ElggAccessCollection|false |
||||||
936 | * |
||||||
937 | * @since 3.0 |
||||||
938 | */ |
||||||
939 | public function getOwnedAccessCollection($subtype) { |
||||||
940 | if (!is_string($subtype) || $subtype === '') { |
||||||
941 | return false; |
||||||
942 | } |
||||||
943 | |||||||
944 | $acls = $this->getOwnedAccessCollections([ |
||||||
945 | 'subtype' => $subtype, |
||||||
946 | ]); |
||||||
947 | |||||||
948 | return elgg_extract(0, $acls, false); |
||||||
949 | } |
||||||
950 | |||||||
951 | /** |
||||||
952 | * Gets an array of entities with a relationship to this entity. |
||||||
953 | * |
||||||
954 | * @param array $options Options array. See elgg_get_entities_from_relationship() |
||||||
955 | * for a list of options. 'relationship_guid' is set to |
||||||
956 | * this entity. |
||||||
957 | * |
||||||
958 | * @return array|false An array of entities or false on failure |
||||||
959 | * @see elgg_get_entities_from_relationship() |
||||||
960 | */ |
||||||
961 | public function getEntitiesFromRelationship(array $options = []) { |
||||||
962 | $options['relationship_guid'] = $this->guid; |
||||||
963 | return elgg_get_entities($options); |
||||||
0 ignored issues
–
show
|
|||||||
964 | } |
||||||
965 | |||||||
966 | /** |
||||||
967 | * Gets the number of entities from a specific relationship type |
||||||
968 | * |
||||||
969 | * @param string $relationship Relationship type (eg "friends") |
||||||
970 | * @param bool $inverse_relationship Invert relationship |
||||||
971 | * |
||||||
972 | * @return int|false The number of entities or false on failure |
||||||
973 | */ |
||||||
974 | public function countEntitiesFromRelationship($relationship, $inverse_relationship = false) { |
||||||
975 | return elgg_get_entities([ |
||||||
976 | 'relationship' => $relationship, |
||||||
977 | 'relationship_guid' => $this->getGUID(), |
||||||
978 | 'inverse_relationship' => $inverse_relationship, |
||||||
979 | 'count' => true |
||||||
980 | ]); |
||||||
981 | } |
||||||
982 | |||||||
983 | /** |
||||||
984 | * Can a user edit this entity? |
||||||
985 | * |
||||||
986 | * @tip Can be overridden by registering for the permissions_check plugin hook. |
||||||
987 | * |
||||||
988 | * @param int $user_guid The user GUID, optionally (default: logged in user) |
||||||
989 | * |
||||||
990 | * @return bool Whether this entity is editable by the given user. |
||||||
991 | * @see elgg_set_ignore_access() |
||||||
992 | */ |
||||||
993 | 399 | public function canEdit($user_guid = 0) { |
|||||
994 | 399 | return _elgg_services()->userCapabilities->canEdit($this, $user_guid); |
|||||
995 | } |
||||||
996 | |||||||
997 | /** |
||||||
998 | * Can a user delete this entity? |
||||||
999 | * |
||||||
1000 | * @tip Can be overridden by registering for the permissions_check:delete plugin hook. |
||||||
1001 | * |
||||||
1002 | * @param int $user_guid The user GUID, optionally (default: logged in user) |
||||||
1003 | * |
||||||
1004 | * @return bool Whether this entity is deletable by the given user. |
||||||
1005 | * @since 1.11 |
||||||
1006 | * @see elgg_set_ignore_access() |
||||||
1007 | */ |
||||||
1008 | 462 | public function canDelete($user_guid = 0) { |
|||||
1009 | 462 | return _elgg_services()->userCapabilities->canDelete($this, $user_guid); |
|||||
1010 | } |
||||||
1011 | |||||||
1012 | /** |
||||||
1013 | * Can a user edit metadata on this entity? |
||||||
1014 | * |
||||||
1015 | * If no specific metadata is passed, it returns whether the user can |
||||||
1016 | * edit any metadata on the entity. |
||||||
1017 | * |
||||||
1018 | * @tip Can be overridden by by registering for the permissions_check:metadata |
||||||
1019 | * plugin hook. |
||||||
1020 | * |
||||||
1021 | * @param \ElggMetadata $metadata The piece of metadata to specifically check or null for any metadata |
||||||
1022 | * @param int $user_guid The user GUID, optionally (default: logged in user) |
||||||
1023 | * |
||||||
1024 | * @return bool |
||||||
1025 | * @see elgg_set_ignore_access() |
||||||
1026 | */ |
||||||
1027 | 338 | public function canEditMetadata($metadata = null, $user_guid = 0) { |
|||||
1028 | 338 | return _elgg_services()->userCapabilities->canEditMetadata($this, $user_guid, $metadata); |
|||||
1029 | } |
||||||
1030 | |||||||
1031 | /** |
||||||
1032 | * Can a user add an entity to this container |
||||||
1033 | * |
||||||
1034 | * @param int $user_guid The GUID of the user creating the entity (0 for logged in user). |
||||||
1035 | * @param string $type The type of entity we're looking to write |
||||||
1036 | * @param string $subtype The subtype of the entity we're looking to write |
||||||
1037 | * |
||||||
1038 | * @return bool |
||||||
1039 | * @see elgg_set_ignore_access() |
||||||
1040 | */ |
||||||
1041 | 407 | public function canWriteToContainer($user_guid = 0, $type = 'all', $subtype = 'all') { |
|||||
1042 | 407 | return _elgg_services()->userCapabilities->canWriteToContainer($this, $user_guid, $type, $subtype); |
|||||
1043 | } |
||||||
1044 | |||||||
1045 | /** |
||||||
1046 | * Can a user comment on an entity? |
||||||
1047 | * |
||||||
1048 | * @tip Can be overridden by registering for the permissions_check:comment, |
||||||
1049 | * <entity type> plugin hook. |
||||||
1050 | * |
||||||
1051 | * @param int $user_guid User guid (default is logged in user) |
||||||
1052 | * @param bool $default Default permission |
||||||
1053 | * @return bool |
||||||
1054 | */ |
||||||
1055 | 4 | public function canComment($user_guid = 0, $default = null) { |
|||||
1056 | 4 | return _elgg_services()->userCapabilities->canComment($this, $user_guid, $default); |
|||||
1057 | } |
||||||
1058 | |||||||
1059 | /** |
||||||
1060 | * Can a user annotate an entity? |
||||||
1061 | * |
||||||
1062 | * @tip Can be overridden by registering for the plugin hook [permissions_check:annotate:<name>, |
||||||
1063 | * <entity type>] or [permissions_check:annotate, <entity type>]. The hooks are called in that order. |
||||||
1064 | * |
||||||
1065 | * @tip If you want logged out users to annotate an object, do not call |
||||||
1066 | * canAnnotate(). It's easier than using the plugin hook. |
||||||
1067 | * |
||||||
1068 | * @param int $user_guid User guid (default is logged in user) |
||||||
1069 | * @param string $annotation_name The name of the annotation (default is unspecified) |
||||||
1070 | * |
||||||
1071 | * @return bool |
||||||
1072 | */ |
||||||
1073 | 8 | public function canAnnotate($user_guid = 0, $annotation_name = '') { |
|||||
1074 | 8 | return _elgg_services()->userCapabilities->canAnnotate($this, $user_guid, $annotation_name); |
|||||
1075 | } |
||||||
1076 | |||||||
1077 | /** |
||||||
1078 | * Returns the access_id. |
||||||
1079 | * |
||||||
1080 | * @return int The access ID |
||||||
1081 | */ |
||||||
1082 | public function getAccessID() { |
||||||
1083 | return $this->access_id; |
||||||
1084 | } |
||||||
1085 | |||||||
1086 | /** |
||||||
1087 | * Returns the guid. |
||||||
1088 | * |
||||||
1089 | * @return int|null GUID |
||||||
1090 | */ |
||||||
1091 | 548 | public function getGUID() { |
|||||
1092 | 548 | return $this->guid; |
|||||
1093 | } |
||||||
1094 | |||||||
1095 | /** |
||||||
1096 | * Returns the entity type |
||||||
1097 | * |
||||||
1098 | * @return string The entity type |
||||||
1099 | */ |
||||||
1100 | 1 | public function getType() { |
|||||
1101 | // this is just for the PHPUnit mocking framework |
||||||
1102 | 1 | return $this->type; |
|||||
1103 | } |
||||||
1104 | |||||||
1105 | /** |
||||||
1106 | * Get the entity subtype |
||||||
1107 | * |
||||||
1108 | * @return string The entity subtype |
||||||
1109 | */ |
||||||
1110 | 566 | public function getSubtype() { |
|||||
1111 | 566 | return $this->attributes['subtype']; |
|||||
1112 | } |
||||||
1113 | |||||||
1114 | /** |
||||||
1115 | * Get the guid of the entity's owner. |
||||||
1116 | * |
||||||
1117 | * @return int The owner GUID |
||||||
1118 | */ |
||||||
1119 | 95 | public function getOwnerGUID() { |
|||||
1120 | 95 | return (int) $this->owner_guid; |
|||||
1121 | } |
||||||
1122 | |||||||
1123 | /** |
||||||
1124 | * Gets the \ElggEntity that owns this entity. |
||||||
1125 | * |
||||||
1126 | * @return \ElggEntity The owning entity |
||||||
1127 | */ |
||||||
1128 | 414 | public function getOwnerEntity() { |
|||||
1129 | 414 | return get_entity($this->owner_guid); |
|||||
1130 | } |
||||||
1131 | |||||||
1132 | /** |
||||||
1133 | * Set the container for this object. |
||||||
1134 | * |
||||||
1135 | * @param int $container_guid The ID of the container. |
||||||
1136 | * |
||||||
1137 | * @return bool |
||||||
1138 | */ |
||||||
1139 | 1 | public function setContainerGUID($container_guid) { |
|||||
1140 | 1 | return $this->container_guid = (int) $container_guid; |
|||||
0 ignored issues
–
show
|
|||||||
1141 | } |
||||||
1142 | |||||||
1143 | /** |
||||||
1144 | * Gets the container GUID for this entity. |
||||||
1145 | * |
||||||
1146 | * @return int |
||||||
1147 | */ |
||||||
1148 | 425 | public function getContainerGUID() { |
|||||
1149 | 425 | return (int) $this->container_guid; |
|||||
1150 | } |
||||||
1151 | |||||||
1152 | /** |
||||||
1153 | * Get the container entity for this object. |
||||||
1154 | * |
||||||
1155 | * @return \ElggEntity |
||||||
1156 | * @since 1.8.0 |
||||||
1157 | */ |
||||||
1158 | 420 | public function getContainerEntity() { |
|||||
1159 | 420 | return get_entity($this->getContainerGUID()); |
|||||
1160 | } |
||||||
1161 | |||||||
1162 | /** |
||||||
1163 | * Returns the UNIX epoch time that this entity was last updated |
||||||
1164 | * |
||||||
1165 | * @return int UNIX epoch time |
||||||
1166 | */ |
||||||
1167 | 5 | public function getTimeUpdated() { |
|||||
1168 | 5 | return $this->time_updated; |
|||||
1169 | } |
||||||
1170 | |||||||
1171 | /** |
||||||
1172 | * Gets the URL for this entity. |
||||||
1173 | * |
||||||
1174 | * Plugins can register for the 'entity:url', <type> plugin hook to |
||||||
1175 | * customize the url for an entity. |
||||||
1176 | * |
||||||
1177 | * @return string The URL of the entity |
||||||
1178 | */ |
||||||
1179 | 42 | public function getURL() { |
|||||
1180 | 42 | $url = _elgg_services()->hooks->trigger('entity:url', $this->getType(), ['entity' => $this]); |
|||||
1181 | |||||||
1182 | 42 | if ($url === null || $url === '' || $url === false) { |
|||||
1183 | 39 | return ''; |
|||||
1184 | } |
||||||
1185 | |||||||
1186 | 3 | return elgg_normalize_url($url); |
|||||
1187 | } |
||||||
1188 | |||||||
1189 | /** |
||||||
1190 | * Saves icons using an uploaded file as the source. |
||||||
1191 | * |
||||||
1192 | * @param string $input_name Form input name |
||||||
1193 | * @param string $type The name of the icon. e.g., 'icon', 'cover_photo' |
||||||
1194 | * @param array $coords An array of cropping coordinates x1, y1, x2, y2 |
||||||
1195 | * @return bool |
||||||
1196 | */ |
||||||
1197 | public function saveIconFromUploadedFile($input_name, $type = 'icon', array $coords = []) { |
||||||
1198 | return _elgg_services()->iconService->saveIconFromUploadedFile($this, $input_name, $type, $coords); |
||||||
1199 | } |
||||||
1200 | |||||||
1201 | /** |
||||||
1202 | * Saves icons using a local file as the source. |
||||||
1203 | * |
||||||
1204 | * @param string $filename The full path to the local file |
||||||
1205 | * @param string $type The name of the icon. e.g., 'icon', 'cover_photo' |
||||||
1206 | * @param array $coords An array of cropping coordinates x1, y1, x2, y2 |
||||||
1207 | * @return bool |
||||||
1208 | */ |
||||||
1209 | public function saveIconFromLocalFile($filename, $type = 'icon', array $coords = []) { |
||||||
1210 | return _elgg_services()->iconService->saveIconFromLocalFile($this, $filename, $type, $coords); |
||||||
1211 | } |
||||||
1212 | |||||||
1213 | /** |
||||||
1214 | * Saves icons using a file located in the data store as the source. |
||||||
1215 | * |
||||||
1216 | * @param string $file An ElggFile instance |
||||||
1217 | * @param string $type The name of the icon. e.g., 'icon', 'cover_photo' |
||||||
1218 | * @param array $coords An array of cropping coordinates x1, y1, x2, y2 |
||||||
1219 | * @return bool |
||||||
1220 | */ |
||||||
1221 | public function saveIconFromElggFile(\ElggFile $file, $type = 'icon', array $coords = []) { |
||||||
1222 | return _elgg_services()->iconService->saveIconFromElggFile($this, $file, $type, $coords); |
||||||
1223 | } |
||||||
1224 | |||||||
1225 | /** |
||||||
1226 | * Returns entity icon as an ElggIcon object |
||||||
1227 | * The icon file may or may not exist on filestore |
||||||
1228 | * |
||||||
1229 | * @param string $size Size of the icon |
||||||
1230 | * @param string $type The name of the icon. e.g., 'icon', 'cover_photo' |
||||||
1231 | * @return \ElggIcon |
||||||
1232 | */ |
||||||
1233 | 7 | public function getIcon($size, $type = 'icon') { |
|||||
1234 | 7 | return _elgg_services()->iconService->getIcon($this, $size, $type); |
|||||
1235 | } |
||||||
1236 | |||||||
1237 | /** |
||||||
1238 | * Removes all icon files and metadata for the passed type of icon. |
||||||
1239 | * |
||||||
1240 | * @param string $type The name of the icon. e.g., 'icon', 'cover_photo' |
||||||
1241 | * @return bool |
||||||
1242 | */ |
||||||
1243 | 1 | public function deleteIcon($type = 'icon') { |
|||||
1244 | 1 | return _elgg_services()->iconService->deleteIcon($this, $type); |
|||||
1245 | } |
||||||
1246 | |||||||
1247 | /** |
||||||
1248 | * Returns the timestamp of when the icon was changed. |
||||||
1249 | * |
||||||
1250 | * @param string $size The size of the icon |
||||||
1251 | * @param string $type The name of the icon. e.g., 'icon', 'cover_photo' |
||||||
1252 | * |
||||||
1253 | * @return int|null A unix timestamp of when the icon was last changed, or null if not set. |
||||||
1254 | */ |
||||||
1255 | public function getIconLastChange($size, $type = 'icon') { |
||||||
1256 | return _elgg_services()->iconService->getIconLastChange($this, $size, $type); |
||||||
1257 | } |
||||||
1258 | |||||||
1259 | /** |
||||||
1260 | * Returns if the entity has an icon of the passed type. |
||||||
1261 | * |
||||||
1262 | * @param string $size The size of the icon |
||||||
1263 | * @param string $type The name of the icon. e.g., 'icon', 'cover_photo' |
||||||
1264 | * @return bool |
||||||
1265 | */ |
||||||
1266 | 3 | public function hasIcon($size, $type = 'icon') { |
|||||
1267 | 3 | return _elgg_services()->iconService->hasIcon($this, $size, $type); |
|||||
1268 | } |
||||||
1269 | |||||||
1270 | /** |
||||||
1271 | * Get the URL for this entity's icon |
||||||
1272 | * |
||||||
1273 | * Plugins can register for the 'entity:icon:url', <type> plugin hook |
||||||
1274 | * to customize the icon for an entity. |
||||||
1275 | * |
||||||
1276 | * @param mixed $params A string defining the size of the icon (e.g. tiny, small, medium, large) |
||||||
1277 | * or an array of parameters including 'size' |
||||||
1278 | * @return string The URL |
||||||
1279 | * @since 1.8.0 |
||||||
1280 | */ |
||||||
1281 | 12 | public function getIconURL($params = []) { |
|||||
1282 | 12 | return _elgg_services()->iconService->getIconURL($this, $params); |
|||||
1283 | } |
||||||
1284 | |||||||
1285 | /** |
||||||
1286 | * Save an entity. |
||||||
1287 | * |
||||||
1288 | * @return bool|int |
||||||
1289 | */ |
||||||
1290 | 533 | public function save() { |
|||||
1291 | 533 | $guid = $this->guid; |
|||||
1292 | 533 | if ($guid > 0) { |
|||||
1293 | 194 | $guid = $this->update(); |
|||||
1294 | } else { |
||||||
1295 | 509 | $guid = $this->create(); |
|||||
1296 | 509 | if ($guid && !_elgg_services()->hooks->getEvents()->trigger('create', $this->type, $this)) { |
|||||
1297 | // plugins that return false to event don't need to override the access system |
||||||
1298 | $ia = elgg_set_ignore_access(true); |
||||||
1299 | $this->delete(); |
||||||
1300 | elgg_set_ignore_access($ia); |
||||||
1301 | return false; |
||||||
1302 | } |
||||||
1303 | } |
||||||
1304 | |||||||
1305 | 533 | if ($guid) { |
|||||
1306 | 513 | $this->cache(); |
|||||
1307 | } |
||||||
1308 | |||||||
1309 | 533 | return $guid; |
|||||
1 ignored issue
–
show
|
|||||||
1310 | } |
||||||
1311 | |||||||
1312 | /** |
||||||
1313 | * Create a new entry in the entities table. |
||||||
1314 | * |
||||||
1315 | * Saves the base information in the entities table for the entity. Saving |
||||||
1316 | * the type-specific information is handled in the calling class method. |
||||||
1317 | * |
||||||
1318 | * @warning Entities must have an entry in both the entities table and their type table |
||||||
1319 | * or they will throw an exception when loaded. |
||||||
1320 | * |
||||||
1321 | * @return int The new entity's GUID |
||||||
1322 | * @throws InvalidParameterException If the entity's type has not been set. |
||||||
1323 | * @throws IOException If the new row fails to write to the DB. |
||||||
1324 | */ |
||||||
1325 | 509 | protected function create() { |
|||||
1326 | |||||||
1327 | 509 | $type = $this->attributes['type']; |
|||||
1328 | 509 | if (!in_array($type, \Elgg\Config::getEntityTypes())) { |
|||||
1329 | throw new \InvalidParameterException('Entity type must be one of the allowed types: ' |
||||||
1330 | . implode(', ', \Elgg\Config::getEntityTypes())); |
||||||
1331 | } |
||||||
1332 | |||||||
1333 | 509 | $subtype = $this->attributes['subtype']; |
|||||
1334 | 509 | if (!$subtype) { |
|||||
1335 | throw new \InvalidParameterException("All entities must have a subtype"); |
||||||
1336 | } |
||||||
1337 | |||||||
1338 | 509 | $owner_guid = (int) $this->attributes['owner_guid']; |
|||||
1339 | 509 | $access_id = (int) $this->attributes['access_id']; |
|||||
1340 | 509 | $now = $this->getCurrentTime()->getTimestamp(); |
|||||
1341 | 509 | $time_created = isset($this->attributes['time_created']) ? (int) $this->attributes['time_created'] : $now; |
|||||
1342 | |||||||
1343 | 509 | $container_guid = $this->attributes['container_guid']; |
|||||
1344 | 509 | if ($container_guid == 0) { |
|||||
1345 | 179 | $container_guid = $owner_guid; |
|||||
1346 | 179 | $this->attributes['container_guid'] = $container_guid; |
|||||
1347 | } |
||||||
1348 | 509 | $container_guid = (int) $container_guid; |
|||||
1349 | |||||||
1350 | 509 | if ($access_id == ACCESS_DEFAULT) { |
|||||
1351 | throw new \InvalidParameterException('ACCESS_DEFAULT is not a valid access level. See its documentation in constants.php'); |
||||||
1352 | } |
||||||
1353 | |||||||
1354 | 509 | if ($access_id == ACCESS_FRIENDS) { |
|||||
1355 | throw new \InvalidParameterException('ACCESS_FRIENDS is not a valid access level. See its documentation in constants.php'); |
||||||
1356 | } |
||||||
1357 | |||||||
1358 | 509 | $user_guid = elgg_get_logged_in_user_guid(); |
|||||
1359 | |||||||
1360 | // If given an owner, verify it can be loaded |
||||||
1361 | 509 | if ($owner_guid) { |
|||||
1362 | 402 | $owner = $this->getOwnerEntity(); |
|||||
1363 | 402 | if (!$owner) { |
|||||
1364 | _elgg_services()->logger->error("User $user_guid tried to create a ($type, $subtype), but the given" |
||||||
1365 | . " owner $owner_guid could not be loaded."); |
||||||
1366 | return false; |
||||||
0 ignored issues
–
show
|
|||||||
1367 | } |
||||||
1368 | |||||||
1369 | // If different owner than logged in, verify can write to container. |
||||||
1370 | |||||||
1371 | 402 | if ($user_guid != $owner_guid && !$owner->canWriteToContainer($user_guid, $type, $subtype)) { |
|||||
1372 | _elgg_services()->logger->error("User $user_guid tried to create a ($type, $subtype) with owner" |
||||||
1373 | . " $owner_guid, but the user wasn't permitted to write to the owner's container."); |
||||||
1374 | return false; |
||||||
1375 | } |
||||||
1376 | } |
||||||
1377 | |||||||
1378 | // If given a container, verify it can be loaded and that the current user can write to it |
||||||
1379 | 509 | if ($container_guid) { |
|||||
1380 | 403 | $container = $this->getContainerEntity(); |
|||||
1381 | 403 | if (!$container) { |
|||||
1382 | _elgg_services()->logger->error("User $user_guid tried to create a ($type, $subtype), but the given" |
||||||
1383 | . " container $container_guid could not be loaded."); |
||||||
1384 | return false; |
||||||
0 ignored issues
–
show
|
|||||||
1385 | } |
||||||
1386 | |||||||
1387 | 403 | if (!$container->canWriteToContainer($user_guid, $type, $subtype)) { |
|||||
1388 | _elgg_services()->logger->error("User $user_guid tried to create a ($type, $subtype), but was not" |
||||||
1389 | . " permitted to write to container $container_guid."); |
||||||
1390 | return false; |
||||||
1391 | } |
||||||
1392 | } |
||||||
1393 | |||||||
1394 | // Create primary table row |
||||||
1395 | 509 | $guid = _elgg_services()->entityTable->insertRow((object) [ |
|||||
1396 | 509 | 'type' => $type, |
|||||
1397 | 509 | 'subtype' => $subtype, |
|||||
1398 | 509 | 'owner_guid' => $owner_guid, |
|||||
1399 | 509 | 'container_guid' => $container_guid, |
|||||
1400 | 509 | 'access_id' => $access_id, |
|||||
1401 | 509 | 'time_created' => $time_created, |
|||||
1402 | 509 | 'time_updated' => $now, |
|||||
1403 | 509 | 'last_action' => $now, |
|||||
1404 | 509 | ], $this->attributes); |
|||||
1405 | |||||||
1406 | 509 | if (!$guid) { |
|||||
1407 | throw new \IOException("Unable to save new object's base entity information!"); |
||||||
1408 | } |
||||||
1409 | |||||||
1410 | 509 | $this->attributes['subtype'] = $subtype; |
|||||
1411 | 509 | $this->attributes['guid'] = (int) $guid; |
|||||
1412 | 509 | $this->attributes['time_created'] = (int) $time_created; |
|||||
1413 | 509 | $this->attributes['time_updated'] = (int) $now; |
|||||
1414 | 509 | $this->attributes['last_action'] = (int) $now; |
|||||
1415 | 509 | $this->attributes['container_guid'] = (int) $container_guid; |
|||||
1416 | |||||||
1417 | // We are writing this new entity to cache to make sure subsequent calls |
||||||
1418 | // to get_entity() load the entity from cache and not from the DB. This |
||||||
1419 | // MUST come before the metadata and annotation writes below! |
||||||
1420 | 509 | $this->cache(); |
|||||
1421 | |||||||
1422 | // Save any unsaved metadata |
||||||
1423 | 509 | if (sizeof($this->temp_metadata) > 0) { |
|||||
1424 | 475 | foreach ($this->temp_metadata as $name => $value) { |
|||||
1425 | 475 | if (count($value) == 1) { |
|||||
1426 | // temp metadata is always an array, but if there is only one value return just the value |
||||||
1427 | 475 | $this->$name = $value[0]; |
|||||
1428 | } else { |
||||||
1429 | 475 | $this->$name = $value; |
|||||
1430 | } |
||||||
1431 | } |
||||||
1432 | |||||||
1433 | 475 | $this->temp_metadata = []; |
|||||
1434 | } |
||||||
1435 | |||||||
1436 | // Save any unsaved annotations. |
||||||
1437 | 509 | if (sizeof($this->temp_annotations) > 0) { |
|||||
1438 | 17 | foreach ($this->temp_annotations as $name => $value) { |
|||||
1439 | 17 | $this->annotate($name, $value); |
|||||
1440 | } |
||||||
1441 | |||||||
1442 | 17 | $this->temp_annotations = []; |
|||||
1443 | } |
||||||
1444 | |||||||
1445 | // Save any unsaved private settings. |
||||||
1446 | 509 | if (sizeof($this->temp_private_settings) > 0) { |
|||||
1447 | 44 | foreach ($this->temp_private_settings as $name => $value) { |
|||||
1448 | 44 | $this->setPrivateSetting($name, $value); |
|||||
1449 | } |
||||||
1450 | |||||||
1451 | 44 | $this->temp_private_settings = []; |
|||||
1452 | } |
||||||
1453 | |||||||
1454 | 509 | return $guid; |
|||||
1455 | } |
||||||
1456 | |||||||
1457 | /** |
||||||
1458 | * Update the entity in the database. |
||||||
1459 | * |
||||||
1460 | * @return bool Whether the update was successful. |
||||||
1461 | * |
||||||
1462 | * @throws InvalidParameterException |
||||||
1463 | */ |
||||||
1464 | 194 | protected function update() { |
|||||
1465 | |||||||
1466 | 194 | if (!$this->canEdit()) { |
|||||
1467 | 26 | return false; |
|||||
1468 | } |
||||||
1469 | |||||||
1470 | // give old update event a chance to stop the update |
||||||
1471 | 172 | if (!_elgg_services()->hooks->getEvents()->trigger('update', $this->type, $this)) { |
|||||
1472 | return false; |
||||||
1473 | } |
||||||
1474 | |||||||
1475 | 172 | $this->invalidateCache(); |
|||||
1476 | |||||||
1477 | // See #6225. We copy these after the update event in case a handler changed one of them. |
||||||
1478 | 172 | $guid = (int) $this->guid; |
|||||
1479 | 172 | $owner_guid = (int) $this->owner_guid; |
|||||
1480 | 172 | $access_id = (int) $this->access_id; |
|||||
1481 | 172 | $container_guid = (int) $this->container_guid; |
|||||
1482 | 172 | $time_created = (int) $this->time_created; |
|||||
1483 | 172 | $time = $this->getCurrentTime()->getTimestamp(); |
|||||
1484 | |||||||
1485 | 172 | if ($access_id == ACCESS_DEFAULT) { |
|||||
1486 | throw new \InvalidParameterException('ACCESS_DEFAULT is not a valid access level. See its documentation in constants.php'); |
||||||
1487 | } |
||||||
1488 | |||||||
1489 | 172 | if ($access_id == ACCESS_FRIENDS) { |
|||||
1490 | throw new \InvalidParameterException('ACCESS_FRIENDS is not a valid access level. See its documentation in constants.php'); |
||||||
1491 | } |
||||||
1492 | |||||||
1493 | // Update primary table |
||||||
1494 | 172 | $ret = _elgg_services()->entityTable->updateRow($guid, (object) [ |
|||||
1495 | 172 | 'owner_guid' => $owner_guid, |
|||||
1496 | 172 | 'container_guid' => $container_guid, |
|||||
1497 | 172 | 'access_id' => $access_id, |
|||||
1498 | 172 | 'time_created' => $time_created, |
|||||
1499 | 172 | 'time_updated' => $time, |
|||||
1500 | 172 | 'guid' => $guid, |
|||||
1501 | ]); |
||||||
1502 | 172 | if ($ret === false) { |
|||||
1503 | return false; |
||||||
1504 | } |
||||||
1505 | |||||||
1506 | 172 | $this->attributes['time_updated'] = $time; |
|||||
1507 | |||||||
1508 | 172 | elgg_trigger_after_event('update', $this->type, $this); |
|||||
1509 | |||||||
1510 | // TODO(evan): Move this to \ElggObject? |
||||||
1511 | 172 | if ($this instanceof \ElggObject && isset($this->orig_attributes['access_id'])) { |
|||||
1512 | 5 | update_river_access_by_object($guid, $access_id); |
|||||
1513 | } |
||||||
1514 | |||||||
1515 | 172 | $this->orig_attributes = []; |
|||||
1516 | |||||||
1517 | 172 | $this->cache(); |
|||||
1518 | |||||||
1519 | // Handle cases where there was no error BUT no rows were updated! |
||||||
1520 | 172 | return true; |
|||||
1521 | } |
||||||
1522 | |||||||
1523 | /** |
||||||
1524 | * Loads attributes from the entities table into the object. |
||||||
1525 | * |
||||||
1526 | * @param stdClass $row Object of properties from database row(s) |
||||||
1527 | * |
||||||
1528 | * @return bool |
||||||
1529 | */ |
||||||
1530 | 5313 | protected function load(stdClass $row) { |
|||||
1531 | 5313 | $attributes = array_merge($this->attributes, (array) $row); |
|||||
1532 | |||||||
1533 | 5313 | if (array_diff(self::$primary_attr_names, array_keys($attributes)) !== []) { |
|||||
1534 | // Some primary attributes are missing |
||||||
1535 | return false; |
||||||
1536 | } |
||||||
1537 | |||||||
1538 | 5313 | foreach ($attributes as $name => $value) { |
|||||
1539 | 5313 | if (!in_array($name, self::$primary_attr_names)) { |
|||||
1540 | 24 | $this->setVolatileData("select:$name", $value); |
|||||
1541 | 24 | unset($attributes[$name]); |
|||||
1542 | 24 | continue; |
|||||
1543 | } |
||||||
1544 | |||||||
1545 | 5313 | if (in_array($name, self::$integer_attr_names)) { |
|||||
1546 | 5313 | $attributes[$name] = (int) $value; |
|||||
1547 | } |
||||||
1548 | } |
||||||
1549 | |||||||
1550 | 5313 | $this->attributes = $attributes; |
|||||
1551 | |||||||
1552 | 5313 | $this->cache(); |
|||||
1553 | |||||||
1554 | 5313 | return true; |
|||||
1555 | } |
||||||
1556 | |||||||
1557 | /** |
||||||
1558 | * Load new data from database into existing entity. Overwrites data but |
||||||
1559 | * does not change values not included in the latest data. |
||||||
1560 | * |
||||||
1561 | * @internal This is used when the same entity is selected twice during a |
||||||
1562 | * request in case different select clauses were used to load different data |
||||||
1563 | * into volatile data. |
||||||
1564 | * |
||||||
1565 | * @param stdClass $row DB row with new entity data |
||||||
1566 | * @return bool |
||||||
1567 | * @access private |
||||||
1568 | */ |
||||||
1569 | public function refresh(stdClass $row) { |
||||||
1570 | if ($row instanceof stdClass) { |
||||||
1571 | return $this->load($row); |
||||||
1572 | } |
||||||
1573 | return false; |
||||||
1574 | } |
||||||
1575 | |||||||
1576 | /** |
||||||
1577 | * Disable this entity. |
||||||
1578 | * |
||||||
1579 | * Disabled entities are not returned by getter functions. |
||||||
1580 | * To enable an entity, use {@link \ElggEntity::enable()}. |
||||||
1581 | * |
||||||
1582 | * Recursively disabling an entity will disable all entities |
||||||
1583 | * owned or contained by the parent entity. |
||||||
1584 | * |
||||||
1585 | * You can ignore the disabled field by using {@link access_show_hidden_entities()}. |
||||||
1586 | * |
||||||
1587 | * @note Internal: Disabling an entity sets the 'enabled' column to 'no'. |
||||||
1588 | * |
||||||
1589 | * @param string $reason Optional reason |
||||||
1590 | * @param bool $recursive Recursively disable all contained entities? |
||||||
1591 | * |
||||||
1592 | * @return bool |
||||||
1593 | * @see \ElggEntity::enable() |
||||||
1594 | */ |
||||||
1595 | 5 | public function disable($reason = "", $recursive = true) { |
|||||
1596 | 5 | if (!$this->guid) { |
|||||
1597 | return false; |
||||||
1598 | } |
||||||
1599 | |||||||
1600 | 5 | if (!_elgg_services()->hooks->getEvents()->trigger('disable', $this->type, $this)) { |
|||||
1601 | return false; |
||||||
1602 | } |
||||||
1603 | |||||||
1604 | 5 | if (!$this->canEdit()) { |
|||||
1605 | return false; |
||||||
1606 | } |
||||||
1607 | |||||||
1608 | 5 | if ($this instanceof ElggUser && !$this->isBanned()) { |
|||||
1609 | // temporarily ban to prevent using the site during disable |
||||||
1610 | 1 | $this->ban(); |
|||||
1611 | 1 | $unban_after = true; |
|||||
1612 | } else { |
||||||
1613 | 4 | $unban_after = false; |
|||||
1614 | } |
||||||
1615 | |||||||
1616 | 5 | if ($reason) { |
|||||
1617 | $this->disable_reason = $reason; |
||||||
1 ignored issue
–
show
|
|||||||
1618 | } |
||||||
1619 | |||||||
1620 | 5 | $dbprefix = _elgg_config()->dbprefix; |
|||||
1621 | |||||||
1622 | 5 | $guid = (int) $this->guid; |
|||||
1623 | |||||||
1624 | 5 | if ($recursive) { |
|||||
1625 | // Only disable enabled subentities |
||||||
1626 | 5 | $hidden = access_get_show_hidden_status(); |
|||||
1627 | 5 | access_show_hidden_entities(false); |
|||||
1628 | |||||||
1629 | 5 | $ia = elgg_set_ignore_access(true); |
|||||
1630 | |||||||
1631 | $base_options = [ |
||||||
1632 | 5 | 'wheres' => [ |
|||||
1633 | 5 | "e.guid != $guid", |
|||||
1634 | ], |
||||||
1635 | 'limit' => false, |
||||||
1636 | ]; |
||||||
1637 | |||||||
1638 | 5 | foreach (['owner_guid', 'container_guid'] as $db_column) { |
|||||
1639 | 5 | $options = $base_options; |
|||||
1640 | 5 | $options[$db_column] = $guid; |
|||||
1641 | |||||||
1642 | 5 | $subentities = new \ElggBatch('elgg_get_entities', $options); |
|||||
1643 | 5 | $subentities->setIncrementOffset(false); |
|||||
1644 | |||||||
1645 | 5 | foreach ($subentities as $subentity) { |
|||||
1646 | /* @var $subentity \ElggEntity */ |
||||||
1647 | 2 | if (!$subentity->isEnabled()) { |
|||||
1648 | continue; |
||||||
1649 | } |
||||||
1650 | 2 | add_entity_relationship($subentity->guid, 'disabled_with', $guid); |
|||||
1651 | 5 | $subentity->disable($reason); |
|||||
1652 | } |
||||||
1653 | } |
||||||
1654 | |||||||
1655 | 5 | access_show_hidden_entities($hidden); |
|||||
1656 | 5 | elgg_set_ignore_access($ia); |
|||||
1657 | } |
||||||
1658 | |||||||
1659 | 5 | $this->disableAnnotations(); |
|||||
1660 | |||||||
1661 | $sql = " |
||||||
1662 | 5 | UPDATE {$dbprefix}entities |
|||||
1663 | SET enabled = 'no' |
||||||
1664 | WHERE guid = :guid |
||||||
1665 | "; |
||||||
1666 | $params = [ |
||||||
1667 | 5 | ':guid' => $guid, |
|||||
1668 | ]; |
||||||
1669 | 5 | $disabled = $this->getDatabase()->updateData($sql, false, $params); |
|||||
1670 | |||||||
1671 | 5 | if ($unban_after) { |
|||||
1672 | 1 | $this->unban(); |
|||||
1 ignored issue
–
show
The method
unban() does not exist on ElggEntity . It seems like you code against a sub-type of ElggEntity such as ElggUser .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
1673 | } |
||||||
1674 | |||||||
1675 | 5 | if ($disabled) { |
|||||
1676 | 5 | $this->invalidateCache(); |
|||||
1677 | |||||||
1678 | 5 | $this->attributes['enabled'] = 'no'; |
|||||
1679 | 5 | _elgg_services()->hooks->getEvents()->trigger('disable:after', $this->type, $this); |
|||||
1680 | } |
||||||
1681 | |||||||
1682 | 5 | return (bool) $disabled; |
|||||
1683 | } |
||||||
1684 | |||||||
1685 | /** |
||||||
1686 | * Enable the entity |
||||||
1687 | * |
||||||
1688 | * @warning Disabled entities can't be loaded unless |
||||||
1689 | * {@link access_show_hidden_entities(true)} has been called. |
||||||
1690 | * |
||||||
1691 | * @param bool $recursive Recursively enable all entities disabled with the entity? |
||||||
1692 | * @see access_show_hiden_entities() |
||||||
1693 | * @return bool |
||||||
1694 | */ |
||||||
1695 | 3 | public function enable($recursive = true) { |
|||||
1696 | 3 | $guid = (int) $this->guid; |
|||||
1697 | 3 | if (!$guid) { |
|||||
1698 | return false; |
||||||
1699 | } |
||||||
1700 | |||||||
1701 | 3 | if (!_elgg_services()->hooks->getEvents()->trigger('enable', $this->type, $this)) { |
|||||
1702 | return false; |
||||||
1703 | } |
||||||
1704 | |||||||
1705 | 3 | if (!$this->canEdit()) { |
|||||
1706 | return false; |
||||||
1707 | } |
||||||
1708 | |||||||
1709 | // Override access only visible entities |
||||||
1710 | 3 | $old_access_status = access_get_show_hidden_status(); |
|||||
1711 | 3 | access_show_hidden_entities(true); |
|||||
1712 | |||||||
1713 | 3 | $db = $this->getDatabase(); |
|||||
1714 | 3 | $result = $db->updateData(" |
|||||
1715 | 3 | UPDATE {$db->prefix}entities |
|||||
1716 | SET enabled = 'yes' |
||||||
1717 | 3 | WHERE guid = $guid |
|||||
1718 | "); |
||||||
1719 | |||||||
1720 | 3 | $this->deleteMetadata('disable_reason'); |
|||||
1721 | 3 | $this->enableAnnotations(); |
|||||
1722 | |||||||
1723 | 3 | if ($recursive) { |
|||||
1724 | 3 | $disabled_with_it = elgg_get_entities([ |
|||||
1725 | 3 | 'relationship' => 'disabled_with', |
|||||
1726 | 3 | 'relationship_guid' => $guid, |
|||||
1727 | 'inverse_relationship' => true, |
||||||
1728 | 3 | 'limit' => 0, |
|||||
1729 | ]); |
||||||
1730 | |||||||
1731 | 3 | foreach ($disabled_with_it as $e) { |
|||||
1732 | 1 | $e->enable(); |
|||||
1733 | 1 | remove_entity_relationship($e->guid, 'disabled_with', $guid); |
|||||
1734 | } |
||||||
1735 | } |
||||||
1736 | |||||||
1737 | 3 | access_show_hidden_entities($old_access_status); |
|||||
1738 | |||||||
1739 | 3 | if ($result) { |
|||||
1740 | 3 | $this->attributes['enabled'] = 'yes'; |
|||||
1741 | 3 | _elgg_services()->hooks->getEvents()->trigger('enable:after', $this->type, $this); |
|||||
1742 | } |
||||||
1743 | |||||||
1744 | 3 | return $result; |
|||||
1745 | } |
||||||
1746 | |||||||
1747 | /** |
||||||
1748 | * Is this entity enabled? |
||||||
1749 | * |
||||||
1750 | * @return boolean Whether this entity is enabled. |
||||||
1751 | */ |
||||||
1752 | 8 | public function isEnabled() { |
|||||
1753 | 8 | return $this->enabled == 'yes'; |
|||||
1754 | } |
||||||
1755 | |||||||
1756 | /** |
||||||
1757 | * Deletes the entity. |
||||||
1758 | * |
||||||
1759 | * Removes the entity and its metadata, annotations, relationships, |
||||||
1760 | * river entries, and private data. |
||||||
1761 | * |
||||||
1762 | * Optionally can remove entities contained and owned by this entity. |
||||||
1763 | * |
||||||
1764 | * @warning If deleting recursively, this bypasses ownership of items contained by |
||||||
1765 | * the entity. That means that if the container_guid = $this->guid, the item will |
||||||
1766 | * be deleted regardless of who owns it. |
||||||
1767 | * |
||||||
1768 | * @param bool $recursive If true (default) then all entities which are |
||||||
1769 | * owned or contained by $this will also be deleted. |
||||||
1770 | * |
||||||
1771 | * @return bool |
||||||
1772 | */ |
||||||
1773 | 459 | public function delete($recursive = true) { |
|||||
1774 | // first check if we can delete this entity |
||||||
1775 | // NOTE: in Elgg <= 1.10.3 this was after the delete event, |
||||||
1776 | // which could potentially remove some content if the user didn't have access |
||||||
1777 | 459 | if (!$this->canDelete()) { |
|||||
1778 | 247 | return false; |
|||||
1779 | } |
||||||
1780 | |||||||
1781 | try { |
||||||
1782 | 215 | return _elgg_services()->entityTable->delete($this, $recursive); |
|||||
1783 | } catch (DatabaseException $ex) { |
||||||
1784 | elgg_log($ex->getMessage(), 'ERROR'); |
||||||
1785 | return false; |
||||||
1786 | } |
||||||
1787 | } |
||||||
1788 | |||||||
1789 | /** |
||||||
1790 | * {@inheritdoc} |
||||||
1791 | */ |
||||||
1792 | 5 | public function toObject() { |
|||||
1793 | 5 | $object = $this->prepareObject(new stdClass()); |
|||||
1794 | 5 | $params = ['entity' => $this]; |
|||||
1795 | 5 | $object = _elgg_services()->hooks->trigger('to:object', 'entity', $params, $object); |
|||||
1796 | 5 | return $object; |
|||||
1797 | } |
||||||
1798 | |||||||
1799 | /** |
||||||
1800 | * Prepare an object copy for toObject() |
||||||
1801 | * |
||||||
1802 | * @param stdClass $object Object representation of the entity |
||||||
1803 | * @return stdClass |
||||||
1804 | */ |
||||||
1805 | 5 | protected function prepareObject($object) { |
|||||
1806 | 5 | $object->guid = $this->guid; |
|||||
1807 | 5 | $object->type = $this->getType(); |
|||||
1808 | 5 | $object->subtype = $this->getSubtype(); |
|||||
1809 | 5 | $object->owner_guid = $this->getOwnerGUID(); |
|||||
1810 | 5 | $object->container_guid = $this->getContainerGUID(); |
|||||
1811 | 5 | $object->time_created = date('c', $this->getTimeCreated()); |
|||||
1812 | 5 | $object->time_updated = date('c', $this->getTimeUpdated()); |
|||||
1813 | 5 | $object->url = $this->getURL(); |
|||||
1814 | 5 | $object->read_access = (int) $this->access_id; |
|||||
1815 | 5 | return $object; |
|||||
1816 | } |
||||||
1817 | |||||||
1818 | /* |
||||||
1819 | * LOCATABLE INTERFACE |
||||||
1820 | */ |
||||||
1821 | |||||||
1822 | /** |
||||||
1823 | * Gets the 'location' metadata for the entity |
||||||
1824 | * |
||||||
1825 | * @return string The location |
||||||
1826 | */ |
||||||
1827 | public function getLocation() { |
||||||
1828 | return $this->location; |
||||||
1829 | } |
||||||
1830 | |||||||
1831 | /** |
||||||
1832 | * Sets the 'location' metadata for the entity |
||||||
1833 | * |
||||||
1834 | * @param string $location String representation of the location |
||||||
1835 | * |
||||||
1836 | * @return void |
||||||
1837 | */ |
||||||
1838 | public function setLocation($location) { |
||||||
1839 | $this->location = $location; |
||||||
1840 | } |
||||||
1841 | |||||||
1842 | /** |
||||||
1843 | * Set latitude and longitude metadata tags for a given entity. |
||||||
1844 | * |
||||||
1845 | * @param float $lat Latitude |
||||||
1846 | * @param float $long Longitude |
||||||
1847 | * |
||||||
1848 | * @return void |
||||||
1849 | * @todo Unimplemented |
||||||
1850 | */ |
||||||
1851 | public function setLatLong($lat, $long) { |
||||||
1852 | $this->{"geo:lat"} = $lat; |
||||||
1853 | $this->{"geo:long"} = $long; |
||||||
1854 | } |
||||||
1855 | |||||||
1856 | /** |
||||||
1857 | * Return the entity's latitude. |
||||||
1858 | * |
||||||
1859 | * @return float |
||||||
1860 | * @todo Unimplemented |
||||||
1861 | */ |
||||||
1862 | 3 | public function getLatitude() { |
|||||
1863 | 3 | return (float) $this->{"geo:lat"}; |
|||||
1864 | } |
||||||
1865 | |||||||
1866 | /** |
||||||
1867 | * Return the entity's longitude |
||||||
1868 | * |
||||||
1869 | * @return float |
||||||
1870 | * @todo Unimplemented |
||||||
1871 | */ |
||||||
1872 | 3 | public function getLongitude() { |
|||||
1873 | 3 | return (float) $this->{"geo:long"}; |
|||||
1874 | } |
||||||
1875 | |||||||
1876 | /* |
||||||
1877 | * SYSTEM LOG INTERFACE |
||||||
1878 | */ |
||||||
1879 | |||||||
1880 | /** |
||||||
1881 | * Return an identification for the object for storage in the system log. |
||||||
1882 | * This id must be an integer. |
||||||
1883 | * |
||||||
1884 | * @return int |
||||||
1885 | */ |
||||||
1886 | 350 | public function getSystemLogID() { |
|||||
1887 | 350 | return $this->getGUID(); |
|||||
1888 | } |
||||||
1889 | |||||||
1890 | /** |
||||||
1891 | * For a given ID, return the object associated with it. |
||||||
1892 | * This is used by the system log. It can be called on any Loggable object. |
||||||
1893 | * |
||||||
1894 | * @param int $id GUID. |
||||||
1895 | * @return int GUID |
||||||
1896 | */ |
||||||
1897 | public function getObjectFromID($id) { |
||||||
1898 | return get_entity($id); |
||||||
0 ignored issues
–
show
|
|||||||
1899 | } |
||||||
1900 | |||||||
1901 | /** |
||||||
1902 | * Returns tags for this entity. |
||||||
1903 | * |
||||||
1904 | * @warning Tags must be registered by {@link elgg_register_tag_metadata_name()}. |
||||||
1905 | * |
||||||
1906 | * @param array $tag_names Optionally restrict by tag metadata names. |
||||||
1907 | * |
||||||
1908 | * @return array |
||||||
1909 | */ |
||||||
1910 | public function getTags($tag_names = null) { |
||||||
1911 | if ($tag_names && !is_array($tag_names)) { |
||||||
1912 | $tag_names = [$tag_names]; |
||||||
1913 | } |
||||||
1914 | |||||||
1915 | $valid_tags = elgg_get_registered_tag_metadata_names(); |
||||||
1916 | $entity_tags = []; |
||||||
1917 | |||||||
1918 | foreach ($valid_tags as $tag_name) { |
||||||
1919 | if (is_array($tag_names) && !in_array($tag_name, $tag_names)) { |
||||||
1920 | continue; |
||||||
1921 | } |
||||||
1922 | |||||||
1923 | if ($tags = $this->$tag_name) { |
||||||
1924 | // if a single tag, metadata returns a string. |
||||||
1925 | // if multiple tags, metadata returns an array. |
||||||
1926 | if (is_array($tags)) { |
||||||
1927 | $entity_tags = array_merge($entity_tags, $tags); |
||||||
1928 | } else { |
||||||
1929 | $entity_tags[] = $tags; |
||||||
1930 | } |
||||||
1931 | } |
||||||
1932 | } |
||||||
1933 | |||||||
1934 | return $entity_tags; |
||||||
1935 | } |
||||||
1936 | |||||||
1937 | /** |
||||||
1938 | * Remove the membership of all access collections for this entity (if the entity is a user) |
||||||
1939 | * |
||||||
1940 | * @return bool |
||||||
1941 | * @since 1.11 |
||||||
1942 | */ |
||||||
1943 | 214 | public function deleteAccessCollectionMemberships() { |
|||||
1944 | |||||||
1945 | 214 | if (!$this->guid) { |
|||||
1946 | return false; |
||||||
1947 | } |
||||||
1948 | |||||||
1949 | 214 | if ($this->type !== 'user') { |
|||||
1950 | 191 | return true; |
|||||
1951 | } |
||||||
1952 | |||||||
1953 | 70 | $ac = _elgg_services()->accessCollections; |
|||||
1954 | |||||||
1955 | 70 | $collections = $ac->getCollectionsByMember($this->guid); |
|||||
1956 | 70 | if (empty($collections)) { |
|||||
1957 | 69 | return true; |
|||||
1958 | } |
||||||
1959 | |||||||
1960 | 4 | $result = true; |
|||||
1961 | 4 | foreach ($collections as $collection) { |
|||||
1962 | 4 | $result = $result & $ac->removeUser($this->guid, $collection->id); |
|||||
1963 | } |
||||||
1964 | |||||||
1965 | 4 | return $result; |
|||||
1966 | } |
||||||
1967 | |||||||
1968 | /** |
||||||
1969 | * Remove all access collections owned by this entity |
||||||
1970 | * |
||||||
1971 | * @return bool |
||||||
1972 | * @since 1.11 |
||||||
1973 | */ |
||||||
1974 | 214 | public function deleteOwnedAccessCollections() { |
|||||
1975 | |||||||
1976 | 214 | if (!$this->guid) { |
|||||
1977 | return false; |
||||||
1978 | } |
||||||
1979 | |||||||
1980 | 214 | $collections = $this->getOwnedAccessCollections(); |
|||||
1981 | 214 | if (empty($collections)) { |
|||||
1982 | 208 | return true; |
|||||
1983 | } |
||||||
1984 | |||||||
1985 | 45 | $result = true; |
|||||
1986 | 45 | foreach ($collections as $collection) { |
|||||
1987 | 45 | $result = $result & $collection->delete(); |
|||||
1988 | } |
||||||
1989 | |||||||
1990 | 45 | return $result; |
|||||
1991 | } |
||||||
1992 | |||||||
1993 | /** |
||||||
1994 | * Update the last_action column in the entities table. |
||||||
1995 | * |
||||||
1996 | * @warning This is different to time_updated. Time_updated is automatically set, |
||||||
1997 | * while last_action is only set when explicitly called. |
||||||
1998 | * |
||||||
1999 | * @param int $posted Timestamp of last action |
||||||
2000 | * @return int|false |
||||||
2001 | * @access private |
||||||
2002 | */ |
||||||
2003 | 122 | public function updateLastAction($posted = null) { |
|||||
2004 | 122 | $posted = _elgg_services()->entityTable->updateLastAction($this, $posted); |
|||||
2005 | 122 | if ($posted) { |
|||||
2006 | 122 | $this->attributes['last_action'] = $posted; |
|||||
2007 | 122 | $this->cache(); |
|||||
2008 | } |
||||||
2009 | 122 | return $posted; |
|||||
2010 | } |
||||||
2011 | |||||||
2012 | /** |
||||||
2013 | * Disable runtime caching for entity |
||||||
2014 | * |
||||||
2015 | * @return void |
||||||
2016 | * @internal |
||||||
2017 | */ |
||||||
2018 | 2 | public function disableCaching() { |
|||||
2019 | 2 | $this->_is_cacheable = false; |
|||||
2020 | 2 | if ($this->guid) { |
|||||
2021 | 2 | _elgg_services()->entityCache->delete($this->guid); |
|||||
2022 | } |
||||||
2023 | 2 | } |
|||||
2024 | |||||||
2025 | /** |
||||||
2026 | * Enable runtime caching for entity |
||||||
2027 | * |
||||||
2028 | * @return void |
||||||
2029 | * @internal |
||||||
2030 | */ |
||||||
2031 | 1 | public function enableCaching() { |
|||||
2032 | 1 | $this->_is_cacheable = true; |
|||||
2033 | 1 | } |
|||||
2034 | |||||||
2035 | /** |
||||||
2036 | * Is entity cacheable in the runtime cache |
||||||
2037 | * |
||||||
2038 | * @return bool |
||||||
2039 | * @internal |
||||||
2040 | */ |
||||||
2041 | 5308 | public function isCacheable() { |
|||||
2042 | 5308 | if (_elgg_services()->session->getIgnoreAccess()) { |
|||||
2043 | 827 | return false; |
|||||
2044 | } |
||||||
2045 | 5118 | return $this->_is_cacheable; |
|||||
2046 | } |
||||||
2047 | |||||||
2048 | /** |
||||||
2049 | * Cache the entity in a session and persisted caches |
||||||
2050 | * |
||||||
2051 | * @param bool $persist Store in persistent cache |
||||||
2052 | * |
||||||
2053 | * @return void |
||||||
2054 | * @internal |
||||||
2055 | */ |
||||||
2056 | 5313 | public function cache($persist = true) { |
|||||
2057 | 5313 | if (!$this->isCacheable()) { |
|||||
2058 | 828 | return; |
|||||
2059 | } |
||||||
2060 | |||||||
2061 | 5125 | _elgg_services()->entityCache->save($this); |
|||||
2062 | |||||||
2063 | 5125 | if ($persist) { |
|||||
2064 | 5125 | $tmp = $this->volatile; |
|||||
2065 | |||||||
2066 | // don't store volatile data |
||||||
2067 | 5125 | $this->volatile = []; |
|||||
2068 | |||||||
2069 | 5125 | _elgg_services()->dataCache->entities->save($this->guid, $this); |
|||||
2070 | |||||||
2071 | 5125 | $this->volatile = $tmp; |
|||||
2072 | } |
||||||
2073 | 5125 | } |
|||||
2074 | |||||||
2075 | /** |
||||||
2076 | * Invalidate cache for entity |
||||||
2077 | * |
||||||
2078 | * @return void |
||||||
2079 | * @internal |
||||||
2080 | */ |
||||||
2081 | 1068 | public function invalidateCache() { |
|||||
2082 | 1068 | if (!$this->guid) { |
|||||
2083 | return; |
||||||
2084 | } |
||||||
2085 | |||||||
2086 | 1068 | _elgg_services()->boot->invalidateCache(); |
|||||
2087 | |||||||
2088 | 1068 | _elgg_services()->entityCache->delete($this->guid); |
|||||
2089 | |||||||
2090 | $namespaces = [ |
||||||
2091 | 1068 | 'entities', |
|||||
2092 | 'metadata', |
||||||
2093 | 'private_settings', |
||||||
2094 | ]; |
||||||
2095 | |||||||
2096 | 1068 | foreach ($namespaces as $namespace) { |
|||||
2097 | 1068 | _elgg_services()->dataCache->get($namespace)->delete($this->guid); |
|||||
2098 | } |
||||||
2099 | 1068 | } |
|||||
2100 | } |
||||||
2101 |