Engine/DataModel/Metadata

We're rewriting our docs. This page has been ported to github. Join the effort!

Metadata in Elgg allows you to store extra data on an entity beyond the built-in fields that entity supports. For example, ElggObjects only support the basic entity fields plus title and description, but you might want to include tags or an ISBN number. Similarly, you might want users to be able to save a date of birth.

Under the hood, metadata is stored as an instance of the ElggMetadata class, but you don't need to worry about that in practice (although if you're interested, see the ElggMetadata class reference). What you need to know is:

  • Metadata has an owner and access ID, both of which may be different to the owner of the entity it's attached to
  • You can potentially have multiple items of each type of metadata attached to a single entity

Contents

The simple case

Adding metadata

To add a piece of metadata to an entity, just call:

$entity->metadata_name = $metadata_value;

For example, to add a date of birth to a user:

$user->dob = $dob_timestamp;

Or to add a couple of tags to an object:

$object->tags = array('tag one', 'tag two', 'tag three');

When adding metadata like this:

  • The owner is set to the currently logged-in user
  • Access permissions are inherited from the entity
  • Reassigning a piece of metadata will overwrite the old value

This is suitable for most purposes. Be careful to note which attributes are metadata and which are built in to the entity type that you are working with. You do not need to save an entity after adding or updating metadata. You do need to save an entity if you have changed one of its built in attributes. As an example, if you changed the access id of an ElggObject, you need to save it or the change isn't pushed to the database.

Reading metadata

To retrieve metadata, treat it as a property of the entity:

$tags_value = $object->tags;

Note that this will return the absolute value of the metadata. To get metadata as an ElggMetadata object, you will need to use the methods described in the finer control section below.

If you stored multiple values in this piece of metadata (as in the "tags" example above), you will get an array of all those values back. If you stored only one value, you will get a string or integer back. Storing an array with only one value will return a string back to you. E.g.

$object->tags = array('tag');
$tags = $object->tags; //$tags == "tag" NOT array('tag')

Finer control

Adding metadata

If you need more control, for example to assign an access ID other than the default, you can use the create_metadata function, which is defined as follows:

	function create_metadata(
		$entity_guid,           // The GUID of the parent entity
		$name,                  // The name of the metadata (eg 'tags')
		$value,                 // The metadata value
		$value_type,            // Currently either 'string' or 'integer'
		$owner_guid,            // The owner of the metadata
		$access_id = 0,         // The access restriction
		$allow_multiple = false // Do we have more than one value?
		)

For single values, you can therefore write metadata as follows (taking the example of a date of birth attached to a user):

create_metadata($user_guid, 'dob', $dob_timestamp, 'integer', $_SESSION['guid'], $access_id);

For multiple values, you will need to iterate through and call create_metadata on each one. The following piece of code comes from the profile save action:

$i = 0;
foreach($value as $interval) {
	$i++;
	if ($i == 1) { $multiple = false; } else { $multiple = true; }
	create_metadata($user->guid, $shortname, $interval, 'text', $user->guid, $access_id, $multiple);
}

Note that the allow multiple setting is set to false in the first iteration and true thereafter.

Reading metadata

A number of functions are available to retrieve metadata as ElggMetadata objects. Click here for a complete list of metadata functions, but here are some:

By name

function get_metadata_byname (
                     $entity_guid,
                     $meta_name	 
                     )

The above retrieves a piece of metadata by name. For example:

$dob = get_metadata_byname($user_guid, 'dob');

Get all metadata for an entity

function get_metadata_for_entity (
                     $entity_guid
                     )

This will return an array containing all of the accessible metadata for a specified entity.

Common mistakes

"Appending" metadata

Note that you cannot "append" values to metadata arrays as if they were normal php arrays. For example, the following will not do what it looks like it should do.

$object->tags[] = "tag four";

Trying to store hashmaps

Elgg does not support storing ordered maps (name/value pairs) in metadata. For example, the following does not work as you might first expect it to:

// Won't work!!
$object->tags = array('one' => 'a', 'two' => 'b', 'three' => 'c');

You can instead store the information like so:

$object->one = 'a';
$object->two = 'b';
$object->three = 'c';

Storing GUIDs in metadata

Though this is not technically incorrect, it is inadvisable to use metadata to store guids. Relationships are a much better construct for this purpose. Yes, there are core plugins that break this principle -- we are working on fixing them!

For example, instead of:

$object->example_guid = $guid;

do:

$object->addRelationship('example', $guid);

Also see

Search docs