Hi Kevin, many thanks for your answer.
I had already read the code, I asked the question although I had already found that there was no implemented post-delete notification system implemented. It was kind of message in a bottle.
The workaround I found was to decorate the annotated object upon callback with a new attribute:
if ($event == "delete") $annotated_obj->annotationToBeDeleted = $ann->id;
The following processing then has to check for this attribute. It's ugly, but lightweight and understandable.
However it raises a persistence question...
At first I set the attribute to "$ann", not "$ann->id". I got a warning from inside database.php that an object was being curated for SQL instead of a string (the debated "trim()"). The issue is, I thought that as long as I didn't call "save()" on my object, the new workaround attribute would not be inserted in database. It should be a non-persistent attribute.
Does this mean that I am only authorized to create non-object attributes on the fly?
Have I missed something about saving? (I mean, why does it call the database??)
(perhaps I should hack some traces in the elgg engine code...)
Or is it in the part of the code I'm not showing? :-)
(this last question because I'm aware that I may not be providing all the details necessary)
For information, I called unset on the workaround attribute after processing, so the attribute should not be around too long.
I also checked with entity browser (great plugin!), and the workaround attribute doesn't appear anywhere. So I don't think I'm polluting the database with this hack.
[meta: I seems I create my questions here with status "open", but I can't find that anywhere afterwards]
Everything on an entity is persisted, but certainly not for annotations. I'm not sure why you are seeing the warning.
I think the plan for 1.9 or so is to standardize the events with create:before, create:after for all the various events so this isn't a problem anymore.
I guess if I were trying to do this now I would try to register a callback for the shutdown event when informed of the annotation delete. Can't remember if the event system works with anonymous functions.
@Cash: Thanks for answering.
About the persistency... perhaps I wasn't clear. I wasn't annoyed at "persisted annotations", but at a persisted attribute of an ElggEntity subclass instance. I try to use the proper vocabulary so that I'm sure we're talking about the same thing (I may be wrong). I had two issues, first that it was persisted (I didn't call save()), then that it forbid an object and I had to use id.
Honestly, I'm very sorry but I wouldn't have time to build an SSCCE. My workaround works, so I'll let it drop.
About the events: good decision. :-) By then I'll probably need backward compatibility, but still.
I don't understand about the shutdown event. Isn't that a system event? How does it help me update anything after a delete has occured?
Thanks for your answer!
Elgg *should* call the entity method delete() whenever an entity is deleted. If it is not, it's a bug and you can open a ticket for this at http://trac.elgg.org/
The function delete_entity() should go away in Elgg 1.9. The original developers tended to write a lot of functions and wrap methods around them. That will be changed in future versions.
lib/entities.php does !
function delete_entity($guid, $recursive = true)
and <entity>->delete
ps: what might the (design) replacement for delete_entity() be @1.9 ?
Update, because in the meantime I've been working. :-)
(questions included at the end)
(side note: I of course totally agree with doing away with functions wrapped in methods, as I demonstrate here... I'm amused by the "original developers" reference... Legacy, you said legacy? :-) )
to answer @Cash: it's true, entity->delete() should always be called. Let me reformulate: there is a non-null risk that delete_entity() is called instead, especially in the scope of the (rather long) plug-in I'm working on, developed by a team. This risk would be absolutely null if...
The second point is probably what's blocking me here, too. Theorically, ElggEntity instances loaded from the database should be of the proper subclass thanks to register_entity_type. Unfortunately I've run into cases where obviously PHP doesn't know the exact subclass it's manipulating, and the overloaded methods never get called. I must admit if I had more time I might look into this, but we don't live in a perfect world. :-(
My current solution to my delete problem is to add an event handler and a static method in my class, which enables me to code all this functionnally instead of OO.
register_elgg_event_handler('delete', "object", 'myDeleteObject');
function myDeleteObject($event, $object_type, $object) {
if ($object->getSubtype() == JrobinssObject::subtype_str) {
JrobinssObject::onDelete($object);
}
}
Note: how do you format code in this message board??
Works fine for the moment, apart from some spaghetti dependencies.
Question: where do you add event handlers in a plug-in? In start.php?
Question: if two entities are linked by a relationship (as defined by addRelationship) does deleting one have an effect on the other?
Thanks for the help, in any case, it's appreciated!
Oh, and another question: how do you remove delete_entity without breaking existing code? I assume you meant change its implementation to a simple $entity->delete().
Is this in 1.7? The functions used for the OO methods are very outdated and have been deprecated for 1.8. I opened a ticket to address the OO methods themselves: http://trac.elgg.org/ticket/3785
Use elgg_get_entities() to grab the objects instead.
$objects = elgg_get_entities(array(
'type' => 'object',
'subtype' => 'JRobinssSubtype',
'owner_guid' => $user->getGUID(),
'container_guid' => 1234
));
Here are some code snippets from users.php
public function getObjects($subtype="", $limit = 10, $offset = 0) {
return get_user_objects($this->getGUID(), $subtype, $limit, $offset);
}
function get_user_objects($user_guid, $subtype = ELGG_ENTITIES_ANY_VALUE, $limit = 10, $offset = 0, $timelower = 0, $timeupper = 0) {
$ntt = elgg_get_entities(array(
'type' => 'object',
'subtype' => $subtype,
'owner_guid' => $user_guid,
'limit' => $limit,
'offset' => $offset,
'container_guid' => $user_guid,
'created_time_lower' => $timelower,
'created_time_upper' => $timeupper
));
return $ntt;
}
I seems that you're right and there's a bug in there, container_guid is set to user_guid.
Thanks for the tip. Apparently I hadn't checked that, which is strange (I thought I had), probably because I thought I found the bug elsewhere. Live and learn.
Many thanks!
info@elgg.org
Security issues should be reported to security@elgg.org!
©2014 the Elgg Foundation
Elgg is a registered trademark of Thematic Networks.
Cover image by Raül Utrera is used under Creative Commons license.
Icons by Flaticon and FontAwesome.