Entity List spec

It's my understanding that something like an entity list will eventually make it into core, but I have an immediate need for this and must push forward coming up with an API that I can implement now in a plugin. I think it'd be mutually beneficial to make my implementation as close to the final one as possible, so I welcome input here.

My main idea is that an ElggList should be a lightweight tool rather than being a full blown ElggObject. Two new tables:

  • elgg_lists: list_id (AUTOINC), key_sha1 (char 40, default NULL)
  • elgg_list_items: list_id, item_id (int, NOT NULL), weight (int, default NULL)

API usage:

$list = new ElggList(); // list with NULL alias

...or

$list = new ElggList("user:123|stickyPages");

$list->id // (read only)

$list->setItems($arrayOfGuids); // most efficient way to establish a list

$list[] = $guid; // adds an item row

array_shift($list); // remove first row

You could always reference a list by ID (available via $list->id), but you could store the SHA1 of a string in `key` like in my original proposal. If key is given, it should be unique across lists.

$list->key = "user:123|stickyPages"; // or set it in the constructor

Static methods findById($id) and findByKey($key) that would return null if not found.

If someone wanted a list to have a name/description, they could just make an object and hold a reference to the list's ID in metadata:

$photoAlbum->list_id = $list->id;

Then we need API methods to JOIN the elgg_list_items table inside get_entities in various ways. E.g.:

$listEntities = elgg_get_entities_in_list($list->id);
$markup = elgg_list_entities_in_list($list->id);
$entitiesSortedByList = elgg_get_entities(array(
    'sortByList' => $list->id
));

So... thoughts?

  • Hi Cash,

    In the case of clear hierarchies (eg. plugins in a site, photos in an album, a page hierarchy) would not the standard display_order option suffice?

    I agree that widgets are a different case because a given widget can appear on multiple pages so having the ability to specify a different ordering would help.

  • And, of course the hierarchical relationship is exactly why the current container system would not work with Steve's use case.

    We would need the ability to order relationships, not containers.

  • To add one more thought to this:

    Currently the standard way to allow multiple entities to "contain" the same items is through relationships.

    For example, users can have the "member_of" relationship with multiple groups.

    Relationships now have timestamps but that is the only way to sort group members. To implement Steve's use case, we would need to have other ways to order relationships associated with an entity.

    Does this make sense?

  • And if it does make sense, then perhaps an extra field added to my proposed single table would do the job:

    relationship, guid1, guid2, priority

    (Edited for clarity.)

  • Ahh - would not adding a single priority field to the relationships table do the job as well?

  • @Kevin, Since 1.8, I've been trying to create hierarchical systems via containers, and it's a real pain. Over time I've realized there is a difference between a containing entity (a way to describe a relationship, and build an hierarchy logic) and a containing element (look at it as a DOM element where we want to the entities to show). For example, a widget is not a container per se, rather a placeholder for a collection of entities. Having lists/collection would resolve the problem of excessively adding metadata, e.g. in case when I have an hierarchy of nested placeholders - let's say I have an entity that has a logical division into segments/categories, which further have segments/categories inside, which then contain widgets. The amount of metadata/relationships I have to use to make this work is scary. Having a collection would eliminate that.

    However, I do agree that perhaps Relationships would be a good way to go forward. But then again you would still need to have a collection as an entity that has a guid to establish a relationship.

    @Steve, one more thing to add to the list is the position of the entity in the list. Similar to widgets, you would want to have an ability to control in which column/section/category an entity appears in the rendered list (in case it's rendered e.g. as a table)

     

  • Ismayil, currently any Elgg entity can have any relationship with any other entity. I see no reason to change that.

    All we would be doing would be adding a way of ordering the relationships between one entity and the entities it has a given relationship with.

    I think that would deal with Steve's use case.

    In the case of current containers, we would simply make it clear that Elgg's containers are  one-to-many *and* unordered. If you want something else, use relationships. We can then extend the elgg_get_entities_from_relationship API to support the new ordering feature.

  • My point was that to establish a relationship with a list you would need to create a collection object first. You might as well have a class that defines methods for this subtype.

  • @Ismayil The nice thing about a collection being just a joined table is that a single set of rows can not only order a flat list, but also a hierarchical list, too: you just JOIN the table in with each branch fetch. The priority acts kind of like XPath document order.

    @Kevin My first use case will be each user having a collection of their favorite entities (mainly publication objects synced from Drupal) that they could re-order. Eventually I want to make a topbar menu item "★" that opens a dropdown list of the first 10 or favorites links.

    @Cash/Ismayil I'm with you on collections needing access control/ownership/metadata/name/description, so ElggCollection should probably extend ElggObject.

    My attraction to the "key" idea was to make finding collections one quick query with no joins, but this would also bypass access control, so I'm OK with letting it go. Using a collection will require two access-controlled queries: one to pull the metadata/relationship to find the collection GUID, and another allowing the user to get a reference to the collection.

    Which of (metadata, relationship) is the more appropriate way to link a collection to an entity?

  • @Steve, why not annotate entities? I think all the API you need is already in place. User 'favorite' as annotation name and priority as an annotation value?

Feedback and Planning

Feedback and Planning

Discussions about the past, present, and future of Elgg and this community site.