Data model
Elgg has a simple, but flexible data model. It supports entities, relationships, and extenders:
Entities are roughly nouns. A user, group, or blog post are all examples of entities.
Relationships connect two entities. Two users are friends. A user is a member of a group. A user is notified when another user posts a comment.
Extenders describe entities. There are two types of extenders: metadata and annotations. A photo has 10 views. A file has been downloaded 300 times. A user's location is Brazil. These are examples of data that is stored as metadata or annotations on an entity.
Entities
ElggEntity
is the parent class of all entities. It is an abstract class and is extended by four classes: ElggGroup
, ElggObject
, ElggSite
, and ElggUser
. The Elgg core also provides three subclasses of ElggObject
as shown in the entity inheritance chart. Plugins can create classes that extend any of these classes.
Type and subtype
Each entity has a type that corresponds to its primary class. The types are group, object, site, and user. Each entity can have a subtype. The subtypes allow developers to subclass one of the primary classes. For example, an ElggPlugin
entity has the subtype 'plugin'
. The type and subtype attributes enable the framework to instantiate the correct class when loading an entity from the database.
GUID
Every entity has a unique identifier. It is global for that Elgg instance.
Owner
Entities are owned by other entities. A blog post is owned by the user who wrote it. Widgets are owned by the user whose profile they are on.
Container
Entities can also belong to a container. When a user uploads a file to a group, the file is owned by the user, but its container is the group.
Access
Every entity has an access level. This controls who can view the entity. The access levels provided by Elgg are private (only that user), the user's friends, anyone logged in, and public (everyone).
Database
There are several ways to represent a class inheritance structure in a relational database. Elgg uses the Class Table Inheritance pattern. In this pattern, each class has its own table. Elgg has tables for the first two layers of classes: the superclass, ElggEntity
, and its subclasses. Therefore, loading an entity from the database consists of loading data from two tables. For example, loading an ElggUser
object loads data from the entity table and the user table. The values from these two tables are called the entity's attributes. The framework does not create tables for developer-created subclasses.
Relationships
The ElggRelationship
class describes a connection between two entities. It supports arbitrary relationships, as shown in the following screenshot. The first entity is the subject of the relationship and the second is the object. If Bob "friends" Larry, then a relationship is created with Bob as the subject and Larry as the object.
Extenders
The ElggExtender
class is abstract and is implemented by two subclasses: ElggAnnotation
and ElggMetadata
.
Annotations and metadata are both used to extend and describe entities. They have a name and a value. A user with a favorite color of blue could be represented as metadata with the name of "favorite_color
" and the value of "blue
". A user downloading a file can be captured as an annotation where the name is "download
" and the value is 1
.
Annotations tend to describe something about another user's content: ratings, downloads, views, likes. Metadata is used more often to capture information by the owner of an entity: whether comments are allowed on a blog post, what the tags are for a file, or how many friends to display in a profile widget. In addition, annotations support mathematical operations such as calculating the average rating or the total number of downloads.
It is very easy to add metadata as Elgg uses the magic methods __get()
and __set()
on the entity class. Using the favorite color example again, the favorite color is set with this code:
$user->favorite_color = "blue";
Elgg handles the persisting of the metadata in the database.
Tip
Entity attributes are different from metadata
Each entity type has a set of attributes that are persisted in the entity database tables. Type, subtype, create time, and access level are all attributes. Attributes and metadata are accessed through the same set and get methods:
$access_level = $file->access_id;
They act differently though. When an attribute is changed, the entity's save
method must be called to persist the change. In addition, some attributes cannot be changed (guid, type, and subtype). One last hint with attributes is to always use the convenience method getSubtype()
as it returns the string representation of the subtype rather than accessing it directly ($entity->subtype
).
Database
Elgg uses the Entity Attribute Value model for storing metadata and annotations. This model supports the dynamic addition of metadata as demonstrated in the favorite color example.
The annotation and metadata tables are normalized. Rather than storing the names and values as strings, they are stored as keys into a strings table.
Retrieval functions
Elgg has a set of elgg_get_entities*
functions for retrieving entities based on parameters. These functions take a single argument of an array with key value pairs. For example, getting the five latest blog posts on the site is done with a call to elgg_get_entities()
:
$options = array( 'type' => 'object', 'subtype' => 'blog', 'limit' => 5, ); elgg_get_entities($options);
The functions support querying by any of the properties that have been mentioned:
elgg_get_entities_from_metadata()
elgg_get_entities_from_annotations()
elgg_get_entities_from_relationship()
In addition, there are parallel functions that both retrieve and display lists of entities. They take the same parameters and begin with elgg_list_entities
.
Code location
The code for the data model is located in /engine/lib/
and /engine/classes/
. The class files all start with Elgg: ElggEntity.php
, ElggObject.php
, ElggUser.php
, ElggGroup.php
, ElggMetadata.php
, ElggAnnotation.php
, and ElggRelationship.php
.
Entities: entities.php
, groups.php
, objects.php
, sites.php
, users.php
, filestore.php
, plugins.php
, and widgets.php
Relationships: relationships.php
Extenders: extender.php
, annotations.php
, metadata.php
, metastrings.php
Database access: database.php