database.rst 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902
  1. Database
  2. ########
  3. A thorough discussion of Elgg's data model design and motivation.
  4. .. contents:: Contents
  5. :local:
  6. :depth: 2
  7. Overview
  8. ========
  9. In Elgg, everything runs on a unified data model based on atomic
  10. units of data called entities.
  11. Plugins are discouraged from interacting directly with the database,
  12. which creates a more stable system and a better user experience becase
  13. content created by different plugins can be mixed together in
  14. consistent ways. With this approach, plugins are faster to develop,
  15. and are at the same time much more powerful.
  16. Every entity in the system inherits the ``ElggEntity`` class. This class
  17. controls access permissions, ownership
  18. .. _thumb\|The Elgg data model diagramIn: image:Elgg_data_model.png
  19. You can extend entities with extra information in two ways:
  20. ``Metadata``: This is information describing the entity, usually
  21. added by the author of the entity when the entity is created.
  22. For example, tags, an ISBN number, a file location, or
  23. source language is metadata.
  24. ``Annotations``: This is information about the entity, usually
  25. added by a third party after the entity is created.
  26. For example, ratings, likes, and votes are annotations.
  27. (Comments were before 1.9.)
  28. Datamodel
  29. =========
  30. .. figure:: images/data_model.png
  31. :figwidth: 650
  32. :align: center
  33. :alt: The Elgg data model diagram
  34. The Elgg data model diagram
  35. Entities
  36. ========
  37. ``ElggEntity`` is the base class for the Elgg data model and supports a common set of properties
  38. and methods.
  39. - A numeric Globally Unique IDentifier (See `GUIDs`_).
  40. - Access permissions. (When a plugin requests data, it never gets to
  41. touch data that the current user doesn't have permission to see.)
  42. - An arbitrary subtype (more below).
  43. - An owner.
  44. - The site that the entity belongs to.
  45. - A container, used to associate content with a group or a user.
  46. Types
  47. -----
  48. *Actual* entities will be instances of four different subclasses, each having a distinct **type**
  49. property and their own additional properties and methods.
  50. ======= ============== ===================================================================
  51. Type PHP class Represents
  52. ======= ============== ===================================================================
  53. object ``ElggObject`` Most user-created content, like blog posts, uploads, and bookmarks.
  54. group ``ElggGroup`` An organized group of users with its own profile page
  55. user ``ElggUser`` A system user
  56. site ``ElggSite`` The site served by the Elgg installation
  57. ======= ============== ===================================================================
  58. Each has its own extended API. E.g. objects have a ``title`` and ``description``, users have a
  59. ``username`` and a way to set their password, and so on.
  60. Subtypes
  61. --------
  62. Each entity also has a custom string **subtype**, which plugins use to further specialize the entity.
  63. Elgg makes it easy to query specific subtypes as well as assign them special behaviors and views.
  64. Subtypes are most commonly given to instances of ElggObject to denote the kind of content created.
  65. E.g. the blog plugin creates objects with subtype ``"blog"``.
  66. For historic reasons, the subtype API is a bit complex, but boils down to: write to ``->subtype``
  67. before saving, otherwise always read ``getSubtype()``. Below are more details.
  68. Subtype Gotchas
  69. ---------------
  70. - Before an entity's ``save()`` method is called, the subtype can be set by writing a string to the
  71. ``subtype`` property.
  72. - *Subtype cannot be changed after saving.*
  73. - After saving, you must always use ``getSubtype()`` to read it.
  74. - If no subtype was set, ``""`` is returned, however some parts of the Elgg API (like Views) may map
  75. this value to the string ``"default"``. E.g. a group with ``getSubtype() === ""`` will be rendered
  76. using the view ``"group/default"``.
  77. - Read carefully the documentation for ``elgg_get_entities()`` before trying to match subtypes; this
  78. - API is a bit of a minefield. E.g. you cannot use ``""`` to fetch entities with the default subtype.
  79. GUIDs
  80. -----
  81. A GUID is an integer that uniquely identifies every entity in an Elgg
  82. installation (a Globally Unique IDentifier). It's assigned automatically
  83. when the entity is first saved and can never be changed.
  84. Some Elgg API functions work with GUIDs instead of ``ElggEntity`` objects.
  85. ElggObject
  86. ==========
  87. The ``ElggObject`` entity type represents arbitrary content within an
  88. Elgg install; things like blog posts, uploaded files, etc.
  89. Beyond the standard ElggEntity properties, ElggObjects also support:
  90. - ``title`` The title of the object (HTML escaped text)
  91. - ``description`` A description of the object (HTML)
  92. Most other data about the object is generally stored via metadata.
  93. ElggUser
  94. ========
  95. The ``ElggUser`` entity type represents users within an Elgg install.
  96. These will be set to disabled until their accounts have been activated
  97. (unless they were created from within the admin panel).
  98. Beyond the standard ElggEntity properties, ElggUsers also support:
  99. - ``name`` The user's plain text name. e.g. "Hugh Jackman"
  100. - ``username`` Their login name. E.g. "hjackman"
  101. - ``password`` A hashed version of their password
  102. - ``salt`` The salt that their password has been hashed with
  103. - ``email`` Their email address
  104. - ``language`` Their default language code.
  105. - ``code`` Their session code (moved to a separate table in 1.9).
  106. - ``last_action`` The UNIX timestamp of the last time they loaded a page
  107. - ``prev_last_action`` The previous value of ``last_action``
  108. - ``last_login`` The UNIX timestamp of their last log in
  109. - ``prev_last_login`` the previous value of ``last_login``
  110. ElggSite
  111. ========
  112. The ``ElggSite`` entity type represents sites within your Elgg install.
  113. Most installs will have only one.
  114. Beyond the standard ElggEntity properties, ElggSites also support:
  115. - ``name`` The site name
  116. - ``description`` A description of the site
  117. - ``url`` The address of the site
  118. ElggGroup
  119. =========
  120. The ``ElggGroup`` entity type represents an association of Elgg users.
  121. Users can join, leave, and post content to groups.
  122. Beyond the standard ElggEntity properties, ElggGroups also support:
  123. - ``name`` The group's name (HTML escaped text)
  124. - ``description`` A description of the group (HTML)
  125. ``ElggGroup`` has addition methods to manage content and membership.
  126. The Groups plugin
  127. -----------------
  128. Not to be confused with the entity type ``ElggGroup``, Elgg comes with
  129. a plugin called "Groups" that provides a default UI/UX for site users
  130. to interact with groups. Each group is given a discussion forum and a
  131. profile page linking users to content within the group.
  132. You can alter the user experience via the traditional means of extending
  133. plugins or completely replace the Groups plugin with your own.
  134. Because ``ElggGroup`` can be subtyped like all other ElggEntities, you
  135. can have multiple types of groups running on the same site.
  136. Writing a group-aware plugin
  137. ----------------------------
  138. Plugin owners need not worry too much about writing group-aware
  139. functionality, but there are a few key points:
  140. Adding content
  141. ~~~~~~~~~~~~~~
  142. By passing along the group as ``container_guid`` via a hidden input field,
  143. you can use a single form and action to add both user and group content.
  144. Use
  145. `can_write_to_container <http://reference.elgg.org/entities_8php.html#16a972909c7cb75f646cb707be001a6f>`_
  146. to determine whether or not the current user has the right to
  147. add content to a group.
  148. Be aware that you will then need to pass the container GUID
  149. or username to the page responsible for posting and the accompanying
  150. value, so that this can then be stored in your form as a hidden input
  151. field, for easy passing to your actions. Within a "create" action,
  152. you'll need to take in this input field and save it as a property of
  153. your new element (defaulting to the current user's container):
  154. .. code:: php
  155. $user = elgg_get_logged_in_user_entity();
  156. $container_guid = (int)get_input('container_guid');
  157. if ($container_guid) {
  158. if (!can_write_to_container($user->guid, $container_guid)) {
  159. // register error and forward
  160. }
  161. } else {
  162. $container_guid = elgg_get_logged_in_user_guid();
  163. }
  164. $object = new ElggObject;
  165. $object->container_guid = $container_guid;
  166. ...
  167. $container = get_entity($container_guid);
  168. forward($container->getURL());
  169. Usernames and page ownership
  170. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  171. Groups have a simulated username of the form *group:\ GUID*, which you
  172. can get the value of by checking ``$group->username``. If you pass this
  173. username to a page on the URL line as part of the ``username`` variable
  174. (i.e., ``/yourpage?username=group:nnn``), Elgg will automatically
  175. register that group as being the owner of the page (unless overridden).
  176. Juggling users and groups
  177. ~~~~~~~~~~~~~~~~~~~~~~~~~
  178. In fact, ``[[Engine/DataModel/Entities/ElggGroup|ElggGroup]]`` simulates
  179. most of the methods of
  180. ``[[Engine/DataModel/Entities/ElggUser|ElggUser]]``. You can grab the
  181. icon, name etc using the same calls, and if you ask for a group's
  182. friends, you'll get its members. This has been designed specifically for
  183. you to alternate between groups and users in your code easily.
  184. Menu options
  185. ~~~~~~~~~~~~
  186. ***This section is deprecated as of Elgg 1.8***
  187. The final piece of the puzzle, for default groups, is to add a link to
  188. your functionality from the group's profile. Here we'll use the file
  189. plugin as an example.
  190. This involves creating a view within your plugin - in this case
  191. file/menu - which will extend the group's menu. File/menu consists of a
  192. link within paragraph tags that points to the file repository of the
  193. page\_owner():
  194. .. code:: php
  195. <p>
  196. <a href="<?php echo $vars['url']; ?>pg/file/<?php echo page_owner_entity()->username; ?>">
  197. <?php echo elgg_echo("file"); ?>
  198. </a>
  199. </p>
  200. You can then extend the group's menu view with this one, within your
  201. plugin's input function (in this case file\_init):
  202. .. code:: php
  203. extend_view('groups/menu/links', 'file/menu');
  204. Ownership
  205. =========
  206. Entities have a ``owner_guid`` GUID property, which defines its
  207. owner. Typically this refers to the GUID of a user, although sites and
  208. users themselves often have no owner (a value of 0).
  209. The ownership of an entity dictates, in part, whether or not you can
  210. access or edit that entity.
  211. Containers
  212. ==========
  213. In order to easily search content by group or by user, content is generally
  214. set to be "contained" by either the user who posted it, or the group to which
  215. the user posted. This means the new object's ``container_guid`` property
  216. will be set to the GUID of the current ElggUser or the target ElggGroup.
  217. E.g., three blog posts may be owned by different authors, but all be
  218. contained by the group they were posted to.
  219. Note: This is not always true. Comment entities are contained by the object
  220. commented upon, and in some 3rd party plugins the container may be used
  221. to model a parent-child relationship between entities (e.g. a "folder"
  222. object containing a file object).
  223. Annotations
  224. ===========
  225. Annotations are pieces of data attached to an entity that allow users
  226. to leave ratings, or other relevant feedback. A poll plugin might
  227. register votes as annotations. Before Elgg 1.9, comments and group
  228. discussion replies were stored as annotations.
  229. Annotations are stored as instances of the ``ElggAnnotation`` class.
  230. Each annotation has:
  231. - An internal annotation type (like *comment*)
  232. - A value (which can be a string or integer)
  233. - An access permission distinct from the entity it's attached to
  234. - An owner
  235. Adding an annotation
  236. --------------------
  237. The easiest way to annotate is to use the ``annotate`` method on an
  238. entity, which is defined as:
  239. .. code:: php
  240. public function annotate(
  241. $name, // The name of the annotation type (eg 'comment')
  242. $value, // The value of the annotation
  243. $access_id = 0, // The access level of the annotation
  244. $owner_id = 0, // The annotation owner, defaults to current user
  245. $vartype = "" // 'text' or 'integer'
  246. )
  247. For example, to leave a rating on an entity, you might call:
  248. .. code:: php
  249. $entity->annotate('rating', $rating_value, $entity->access_id);
  250. Reading annotations
  251. -------------------
  252. To retrieve annotations on an object, you can call the following method:
  253. .. code:: php
  254. $annotations = $entity->getAnnotations(
  255. $name, // The type of annotation
  256. $limit, // The number to return
  257. $offset, // Any indexing offset
  258. $order, // 'asc' or 'desc' (default 'asc')
  259. );
  260. If your annotation type largely deals with integer values, a couple of
  261. useful mathematical functions are provided:
  262. .. code:: php
  263. $averagevalue = $entity->getAnnotationsAvg($name); // Get the average value
  264. $total = $entity->getAnnotationsSum($name); // Get the total value
  265. $minvalue = $entity->getAnnotationsMin($name); // Get the minimum value
  266. $maxvalue = $entity->getAnnotationsMax($name); // Get the maximum value
  267. Useful helper functions
  268. -----------------------
  269. Comments
  270. ~~~~~~~~
  271. If you want to provide comment functionality on your plugin objects, the
  272. following function will provide the full listing, form and actions:
  273. .. code:: php
  274. function elgg_view_comments(ElggEntity $entity)
  275. Metadata
  276. ========
  277. Metadata in Elgg allows you to store extra data on an ``entity`` beyond
  278. the built-in fields that entity supports. For example, ``ElggObjects``
  279. only support the basic entity fields plus title and description, but you
  280. might want to include tags or an ISBN number. Similarly, you might want
  281. users to be able to save a date of birth.
  282. Under the hood, metadata is stored as an instance of the
  283. ``ElggMetadata`` class, but you don't need to worry about that in
  284. practice (although if you're interested, see the ``ElggMetadata`` class
  285. reference). What you need to know is:
  286. - Metadata has an owner and access ID, both of which may be different
  287. to the owner of the entity it's attached to
  288. - You can potentially have multiple items of each type of metadata
  289. attached to a single entity
  290. The simple case
  291. ---------------
  292. Adding metadata
  293. ~~~~~~~~~~~~~~~
  294. To add a piece of metadata to an entity, just call:
  295. .. code:: php
  296. $entity->metadata_name = $metadata_value;
  297. For example, to add a date of birth to a user:
  298. .. code:: php
  299. $user->dob = $dob_timestamp;
  300. Or to add a couple of tags to an object:
  301. .. code:: php
  302. $object->tags = array('tag one', 'tag two', 'tag three');
  303. When adding metadata like this:
  304. - The owner is set to the currently logged-in user
  305. - Access permissions are inherited from the entity
  306. - Reassigning a piece of metadata will overwrite the old value
  307. This is suitable for most purposes. Be careful to note which attributes
  308. are metadata and which are built in to the entity type that you are
  309. working with. You do not need to save an entity after adding or updating
  310. metadata. You do need to save an entity if you have changed one of its
  311. built in attributes. As an example, if you changed the access id of an
  312. ElggObject, you need to save it or the change isn't pushed to the
  313. database.
  314. Reading metadata
  315. ~~~~~~~~~~~~~~~~
  316. To retrieve metadata, treat it as a property of the entity:
  317. .. code:: php
  318. $tags_value = $object->tags;
  319. Note that this will return the absolute value of the metadata. To get
  320. metadata as an ElggMetadata object, you will need to use the methods
  321. described in the *finer control* section below.
  322. If you stored multiple values in this piece of metadata (as in the
  323. "tags" example above), you will get an array of all those values back.
  324. If you stored only one value, you will get a string or integer back.
  325. Storing an array with only one value will return a string back to you.
  326. E.g.
  327. .. code:: php
  328. $object->tags = array('tag');
  329. $tags = $object->tags;
  330. // $tags will be the string "tag", NOT array('tag')
  331. To always get an array back, simply cast to an array;
  332. .. code:: php
  333. $tags = (array)$object->tags;
  334. Finer control
  335. -------------
  336. Adding metadata
  337. ~~~~~~~~~~~~~~~
  338. If you need more control, for example to assign an access ID other than
  339. the default, you can use the ``create_metadata`` function, which is
  340. defined as follows:
  341. .. code:: php
  342. function create_metadata(
  343. $entity_guid, // The GUID of the parent entity
  344. $name, // The name of the metadata (eg 'tags')
  345. $value, // The metadata value
  346. $value_type, // Currently either 'string' or 'integer'
  347. $owner_guid, // The owner of the metadata
  348. $access_id = 0, // The access restriction
  349. $allow_multiple = false // Do we have more than one value?
  350. )
  351. For single values, you can therefore write metadata as follows (taking
  352. the example of a date of birth attached to a user):
  353. .. code:: php
  354. create_metadata($user_guid, 'dob', $dob_timestamp, 'integer', $_SESSION['guid'], $access_id);
  355. For multiple values, you will need to iterate through and call
  356. ``create_metadata`` on each one. The following piece of code comes from
  357. the profile save action:
  358. .. code:: php
  359. $i = 0;
  360. foreach ($value as $interval) {
  361. $i++;
  362. $multiple = ($i != 1);
  363. create_metadata($user->guid, $shortname, $interval, 'text', $user->guid, $access_id, $multiple);
  364. }
  365. Note that the *allow multiple* setting is set to *false* in the first
  366. iteration and *true* thereafter.
  367. Reading metadata
  368. ~~~~~~~~~~~~~~~~
  369. ``elgg_get_metadata`` is the best function for retrieving metadata as ElggMetadata
  370. objects:
  371. E.g., to retrieve a user's DOB
  372. .. code:: php
  373. elgg_get_metadata(array(
  374. 'metadata_name' => 'dob',
  375. 'metadata_owner_guid' => $user_guid,
  376. ));
  377. Or to get all metadata objects:
  378. .. code:: php
  379. elgg_get_metadata(array(
  380. 'metadata_owner_guid' => $user_guid,
  381. 'limit' => 0,
  382. ));
  383. .. complete list of metadata functions: http://reference.elgg.org/engine_2lib_2metadata_8php.html
  384. Common mistakes
  385. ---------------
  386. "Appending" metadata
  387. ~~~~~~~~~~~~~~~~~~~~
  388. Note that you cannot "append" values to metadata arrays as if they were
  389. normal php arrays. For example, the following will not do what it looks
  390. like it should do.
  391. .. code:: php
  392. $object->tags[] = "tag four";
  393. Trying to store hashmaps
  394. ~~~~~~~~~~~~~~~~~~~~~~~~
  395. Elgg does not support storing ordered maps (name/value pairs) in
  396. metadata. For example, the following does not work as you might first
  397. expect it to:
  398. .. code:: php
  399. // Won't work!! Only the array values are stored
  400. $object->tags = array('one' => 'a', 'two' => 'b', 'three' => 'c');
  401. You can instead store the information like so:
  402. .. code:: php
  403. $object->one = 'a';
  404. $object->two = 'b';
  405. $object->three = 'c';
  406. Storing GUIDs in metadata
  407. ~~~~~~~~~~~~~~~~~~~~~~~~~
  408. Though there are some cases to store entity GUIDs in metadata,
  409. `Relationships`_ are a much better construct for relating entities
  410. to each other.
  411. Relationships
  412. =============
  413. Relationships allow you to bind entities together. Examples: an
  414. artist has fans, a user is a member of an organization, etc.
  415. The class ``ElggRelationship`` models a directed relationship between
  416. two entities, making the statement:
  417. "**{subject}** is a **{noun}** of **{target}**."
  418. ================ =========== =========================================
  419. API name Models Represents
  420. ================ =========== =========================================
  421. ``guid_one`` The subject Which entity is being bound
  422. ``relationship`` The noun The type of relationship
  423. ``guid_two`` The target The entity to which the subject is bound
  424. ================ =========== =========================================
  425. The type of relationship may alternately be a verb, making the statement:
  426. "**{subject}** **{verb}** **{target}**."
  427. E.g. User A "likes" blog post B
  428. **Each relationship has direction.** Imagine an archer shoots
  429. an arrow at a target; The arrow moves in one direction, binding
  430. the subject (the archer) to the target.
  431. **A relationship does not imply reciprocity**. **A** follows **B** does
  432. not imply that **B** follows **A**.
  433. **Relationships_ do not have access control.** They're never
  434. hidden from view and can be edited with code at any privilege
  435. level, with the caveat that *the entities* in a relationship
  436. may be invisible due to access control!
  437. Working with relationships
  438. --------------------------
  439. Creating a relationship
  440. ~~~~~~~~~~~~~~~~~~~~~~~
  441. E.g. to establish that "**$user** is a **fan** of **$artist**"
  442. (user is the subject, artist is the target):
  443. .. code:: php
  444. // option 1
  445. $success = add_entity_relationship($user->guid, 'fan', $artist->guid);
  446. // option 2
  447. $success = $user->addRelationship($artist->guid, 'fan');
  448. This triggers the event [create, relationship], passing in
  449. the created ``ElggRelationship`` object. If a handler returns
  450. ``false``, the relationship will not be created and ``$success``
  451. will be ``false``.
  452. Verifying a relationship
  453. ~~~~~~~~~~~~~~~~~~~~~~~~
  454. E.g. to verify that "**$user** is a **fan** of **$artist**":
  455. .. code:: php
  456. if (check_entity_relationship($user->guid, 'fan', $artist->guid)) {
  457. // relationship exists
  458. }
  459. Note that, if the relationship exists, ``check_entity_relationship()``
  460. returns an ``ElggRelationship`` object:
  461. .. code:: php
  462. $relationship = check_entity_relationship($user->guid, 'fan', $artist->guid);
  463. if ($relationship) {
  464. // use $relationship->id or $relationship->time_created
  465. }
  466. Deleting a relationship
  467. ~~~~~~~~~~~~~~~~~~~~~~~
  468. E.g. to be able to assert that "**$user** is no longer a **fan** of **$artist**":
  469. .. code:: php
  470. $was_removed = remove_entity_relationship($user->guid, 'fan', $artist->guid);
  471. This triggers the event [delete, relationship], passing in
  472. the associated ``ElggRelationship`` object. If a handler returns
  473. ``false``, the relationship will remain, and ``$was_removed`` will
  474. be ``false``.
  475. Other useful functions:
  476. - ``delete_relationship()`` : delete by ID
  477. - ``remove_entity_relationships()`` : delete those relating to an entity (*note:* in versions before Elgg 1.9, this did not trigger delete events)
  478. Finding relationships and related entities
  479. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  480. Below are a few functions to fetch relationship objects
  481. and/or related entities. A few are listed below:
  482. - ``get_entity_relationships()`` : fetch relationships by subject or target entity
  483. - ``get_relationship()`` : get a relationship object by ID
  484. - ``elgg_get_entities_from_relationship()`` : fetch entities in relationships in a
  485. variety of ways
  486. E.g. retrieving users who joined your site in January 2014.
  487. .. code:: php
  488. $entities = elgg_get_entities_from_relationship(array(
  489. 'relationship' => 'member_of_site',
  490. 'relationship_guid' => elgg_get_site_entity()->guid,
  491. 'inverse_relationship' => true,
  492. 'relationship_created_time_lower' => 1388534400, // January 1st 2014
  493. 'relationship_created_time_upper' => 1391212800, // February 1st 2014
  494. ));
  495. Access Control
  496. ==============
  497. Granular access controls are one of the fundamental design principles in
  498. Elgg, and a feature that has been at the centre of the system throughout
  499. its development. The idea is simple: a user should have full control
  500. over who sees an item of data he or she creates.
  501. Access controls in the data model
  502. ---------------------------------
  503. In order to achieve this, every entity, annotation and piece of
  504. metadata contains an ``access_id`` property, which in turn corresponds
  505. to one of the pre-defined access controls or an entry in the
  506. ``access_collections`` database table.
  507. Pre-defined access controls
  508. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  509. - ``ACCESS_PRIVATE`` (value: 0) Private.
  510. - ``ACCESS_LOGGED_IN`` (value: 1) Logged in users.
  511. - ``ACCESS_PUBLIC`` (value: 2) Public data.
  512. - ``ACCESS_FRIENDS`` (value: -2) Owner and his/her friends.
  513. User defined access controls
  514. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  515. You may define additional access groups and assign them to an entity,
  516. annotation or metadata. A number of functions have been defined to
  517. assist you; see the `access library reference`_ for more information.
  518. How access affects data retrieval
  519. ---------------------------------
  520. All data retrieval functions above the database layer - for example
  521. ``get_entities`` and its cousins - will only return items that the
  522. current user has access to see. It is not possible to retrieve items
  523. that the current user does not have access to. This makes it very hard
  524. to create a security hole for retrieval.
  525. .. _access library reference: http://reference.elgg.org/engine_2lib_2access_8php.html
  526. Write access
  527. ------------
  528. The following rules govern write access:
  529. - The owner of an entity can always edit it
  530. - The owner of a container can edit anything therein (note that this
  531. does not mean that the owner of a group can edit anything therein)
  532. - Admins can edit anything
  533. You can override this behaviour using a :ref:`plugin hook <design/events#plugin-hooks>` called
  534. ``permissions_check``, which passes the entity in question to any
  535. function that has announced it wants to be referenced. Returning
  536. ``true`` will allow write access; returning ``false`` will deny it. See
  537. :ref:`the plugin hook reference for permissions\_check <guides/hooks-list#permission-hooks>` for more details.
  538. .. seealso::
  539. `Access library reference`_
  540. .. _Access library reference: http://reference.elgg.org/engine_2lib_2access_8php.html
  541. Schema
  542. ======
  543. The database contains a number of primary tables and secondary tables.
  544. Its schema table is stored in ``/engine/schema/mysql.sql``.
  545. Each table is prefixed by "prefix\_", this is replaced by the Elgg
  546. framework during installation.
  547. Main tables
  548. -----------
  549. This is a description of the main tables. Keep in mind that in a given
  550. Elgg installation, the tables will have a prefix (typically "elgg\_").
  551. Table: entities
  552. ~~~~~~~~~~~~~~~
  553. This is the main `Entities`_ table containing Elgg users, sites,
  554. objects and groups. When you first install Elgg this is automatically
  555. populated with your first site.
  556. It contains the following fields:
  557. - **guid** An auto-incrementing counter producing a GUID that uniquely
  558. identifies this entity in the system.
  559. - **type** The type of entity - object, user, group or site
  560. - **subtype** A reference to the `entity_subtypes` table, or ``0`` for the default subtype.
  561. - **owner\_guid** The GUID of the owner's entity.
  562. - **site\_guid** The site the entity belongs to.
  563. - **container\_guid** The GUID this entity is contained by - either a user or
  564. a group.
  565. - **access\_id** Access controls on this entity.
  566. - **time\_created** Unix timestamp of when the entity is created.
  567. - **time\_updated** Unix timestamp of when the entity was updated.
  568. - **enabled** If this is 'yes' an entity is accessible, if 'no' the entity
  569. has been disabled (Elgg treats it as if it were deleted without actually
  570. removing it from the database).
  571. Table: entity\_subtypes
  572. ~~~~~~~~~~~~~~~~~~~~~~~
  573. This table contains entity subtype information:
  574. - **id** A counter.
  575. - **type** The type of entity - object, user, group or site.
  576. - **subtype** The subtype name as a string.
  577. - **class** Optional class name if this subtype is linked with a class
  578. Table: metadata
  579. ~~~~~~~~~~~~~~~
  580. This table contains `Metadata`_, extra information attached to an entity.
  581. - **id** A counter.
  582. - **entity\_guid** The entity this is attached to.
  583. - **name\_id** A link to the metastrings table defining the name
  584. table.
  585. - **value\_id** A link to the metastrings table defining the value.
  586. - **value\_type** The value class, either text or an integer.
  587. - **owner\_guid** The owner GUID of the owner who set this item of
  588. metadata.
  589. - **access\_id** An Access controls on this item of metadata.
  590. - **time\_created** Unix timestamp of when the metadata is created.
  591. - **enabled** If this is 'yes' an item is accessible, if 'no' the item
  592. has been deleted.
  593. Table: annotations
  594. ~~~~~~~~~~~~~~~~~~
  595. This table contains `Annotations`_, this is distinct from `Metadata`_.
  596. - **id** A counter.
  597. - **entity\_guid** The entity this is attached to.
  598. - **name\_id** A link to the metastrings table defining the type of
  599. annotation.
  600. - **value\_id** A link to the metastrings table defining the value.
  601. - **value\_type** The value class, either text or an integer.
  602. - **owner\_guid** The owner GUID of the owner who set this item of
  603. metadata.
  604. - **access\_id** An Access controls on this item of metadata.
  605. - **time\_created** Unix timestamp of when the metadata is created.
  606. - **enabled** If this is 'yes' an item is accessible, if 'no' the item
  607. has been deleted.
  608. Table: relationships
  609. ~~~~~~~~~~~~~~~~~~~~
  610. This table defines `Relationships`_, these link one entity with another.
  611. - **guid\_one** The GUID of the subject entity.
  612. - **relationship** The type of the relationship.
  613. - **guid\_two** The GUID of the target entity.
  614. Table: objects\_entity
  615. ~~~~~~~~~~~~~~~~~~~~~~
  616. Extra information specifically relating to objects. These are split in
  617. order to reduce load on the metadata table and make an obvious
  618. difference between attributes and metadata.
  619. Table: sites\_entity
  620. ~~~~~~~~~~~~~~~~~~~~
  621. Extra information specifically relating to sites. These are split in
  622. order to reduce load on the metadata table and make an obvious
  623. difference between attributes and metadata.
  624. Table: users\_entity
  625. ~~~~~~~~~~~~~~~~~~~~
  626. Extra information specifically relating to users. These are split in
  627. order to reduce load on the metadata table and make an obvious
  628. difference between attributes and metadata.
  629. Table: groups\_entity
  630. ~~~~~~~~~~~~~~~~~~~~~
  631. Extra information specifically relating to groups. These are split in
  632. order to reduce load on the metadata table and make an obvious
  633. difference between attributes and metadata.
  634. Table: metastrings
  635. ~~~~~~~~~~~~~~~~~~
  636. Metastrings contain the actual string of metadata which is linked to by
  637. the metadata and annotations tables.
  638. This is to avoid duplicating strings, saving space and making database
  639. lookups more efficient.
  640. Core developers will place schema upgrades in
  641. ``/engine/schema/upgrades/*``.