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:
$list = new ElggList(); // list with NULL alias
$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
Good one. Thumbs up. I was actually starting to work on my implementation of this, but eventually gave up as it wasn't really making my life with lists easier.
However, here are my thoughts:
1. I like your original proposal where elgg_get_entities options are stored with the list
2. It would be good to have an ECML compatible key
3. I would encourage more Elggy 'keywords' - 'item_guid' instead of 'item_id', 'priority' instead of 'weight', and same goes for static methods
4. Privileges - who can add items to the list? who can view the list?
5. I would like to see the following methods:
$list->addItems($arrayOfGuids) // there must be a way to specify priority
$list->getItems($options) // options to narrow down the return
$list->removeItems($arrayOfGuids) // there must be a way to re-build the priorities
$list->view() // html markup, must accept an array of $vars to be used in page/components/list
$list->canEdit() // perhaps plugin hooks would suffice
6. Helper API functions
elgg_get_list_by_id() // from here you can use static methods to get list items
elgg_view_list($list_entity, $order_by, $vars)
7. It must be insured that items are removed from the list if the entity is deleted
8. Should the items be added to the list automatically if they match $list->options?
9. It would be good to see lists of mixed type/subtype (not just object/blog, or user/all, but 2 blogs, 3 files etc.)
1. I greatly prefer calling these collections to lists since we already use the term lists in Elgg
2. Agree with Ismayil on using item_guid and priority rather than list_id and weight
3. Why the hash rather than storing the name of the list?
4. Seems lists need owners. How else do you control adding to the lists or knowing what lists a user has?
5. Not making this an entity means no commenting on lists, no notifications based on lists, no activity stream updates on lists, and no relationships with lists without having a paired ElggObject. If we end up with a lot of lists needing the paired ElggObject for one of these reasons, we may end up with a system that is slower than just making it an ElggEntity. We would need to develop a set if use cases to evaluate this. It is easier to promote something to an entity than to demote it so the side to error on is making it not an entity.
6. Your original proposal had a site guid in the list definition. That would allow it to support multi-site Elgg installs.
7. If having a paired ElggObject is going to be a common use case (though not common enough to justify promotion of the list to ElggEntity), I prefer that the link to the ElggObject be built into the list rather than it being metadata.
This is obviously something that we cannot pull into 1.8, but 1.9 seems reasonable.
It is not clear to me from Steve's original post why he needs this feature. Steve can you explain more?
I would especially be concerned about adding new tables as I would argue that the Elgg table structure is already more complex than necessary and a clean and simple data storage system has many advantages.
I just noticed Steve's original proposal link. Sorry I had not noticed that before.
It is common to create a container for a collection of objects and then attach a display_order field to each object.
Is your point that you want to have the same item in multiple lists with a different display_order for each list?
In that case, why not just serialize a list of guids? Is that because it violates the rule of not including guids in metadata?
Serializing GUIDs is clunky and makes clean-up more difficult than it needs to be. if the choice is between adding a list/collection table and using serialized GUIDs, adding the table definitely wins. The fact that the only way to accomplish this right now is with serialized GUIDs means Elgg is lacking something (and yeah, I want to be able put the same entity in multiple collections).
Cash, there is nothing wrong in my view if Elgg is "lacking something".
One of Elgg's major advantages is the clarity and simplicity of its API. The more features that are added, the more code there is to maintain, the more opportunities for bugs, the steeper the learning curve, the fewer the developers there will be and the less popular the application.
I am not saying that there isn't a case to be made here for a new feature but I think that it needs to be stronger than that Elgg is "lacking something".
I think that a case could be made for storing a guid ordering to avoid having to serialize one.
But why create a special collection entity?
Would not a single table:
container_guid, item_guid, priority
do the job?
Any container could optionally have an ordering associated with it.
Items within an ordered collection would contain a reference to a container as usual but developers could optionally store an ordering in an ordering table as well.
So instead of adding the idea of an ElggList or an ElggOrderedCollection we would have the lighter weight idea of an ElggOrdering.
One advantage of the ElggOrdering approach is backwards compatibility. If no ordering was available, Elgg could default to the default behaviour (eg. guid descending).
EDIT: But now that I think more about it, the container approach would not work because it is hierarchical. As I mention below, this would need to work with relationships (many-to-many) instead.
The model that Brett and I have used for adding functionality to Elgg is that Elgg should provide 80% of the functionality for 80% of the developers. This still leaves us with a subjective decision on what should be included and what shouldn't, but it does provide structure for the discussion.
We've been doing some Milestone planning (with the objective of getting input from the wider community soon). Adding collection support was one of the items listed in the near term so it passed the above threshold for the three of us.
The reason I think Elgg needs this is because too many of us are implementing custom collections/ordered lists. We have two custom ordered lists in Elgg core: widgets and plugins. We have had requests to add ordering to pages in the pages plugin. If the sites pages plugin provided the ability to create arbitrary pages, we'd want those to also support arbitrary orderings. Outside of core/bundled plugins, the Tidypics plugin has an implementation of custom ordering. Steve provided a few use cases in his original proposal and I could name several others.