Actualizar complementos

Prepare su complemento para la siguiente versión de Elgg.

See the administrator guides for how to upgrade a live site.


From 2.2 to 2.3

PHP Version

PHP 5.5 has reached end of life in July 2016. To ensure that Elgg sites are secure, we now require PHP 5.6 for new installations.

Existing installations can continue using PHP 5.5 until Elgg 3.0.

In order to upgrade Elgg to 2.3 using composer while using PHP 5.5, you may need to use --ignore-platform-reqs flag.

Deprecated APIs

  • Registering for to:object hook by the extender name: Use to:object, annotation and to:object, metadata hooks instead.
  • ajax_forward_hook(): No longer used as handler for “forward”,”all” hook. Ajax response is now wrapped by the ResponseFactory
  • ajax_action_hook(): No longer used as handler for “action”,”all” hook. Output buffering now starts before the hook is triggered in ActionsService
  • elgg_error_page_handler(): No longer used as a handler for “forward”,<error_code> hooks
  • get_uploaded_file(): Use new file uploads API instead
  • get_user_notification_settings(): Use ElggUser::getNotificationSettings()
  • set_user_notification_setting(): Use ElggUser::setNotificationSetting()
  • pagesetup, system event: Use the menu or page shell hooks instead.
  • elgg.walled_garden JavaScript is deprecated: Use elgg/walled_garden AMD module instead.
  • elgg()->getDb()->getTableprefix(): Use elgg_get_config('dbprefix').
  • Private update_entity_last_action(): Refrain from manually updating last action timestamp.
  • Setting non-public access_id on metadata is deprecated. See below.
  • get_resized_image_from_existing_file(): Use elgg_save_resized_image().
  • get_resized_image_from_uploaded_file(): Use elgg_save_resized_image() in combination with upload API.
  • get_image_resize_parameters() will be removed.
  • elgg_view_input(): Use elgg_view_field(). Apologies for the API churn.

Deprecated Views

  • resources/file/world: Use the resources/file/all view instead.
  • resources/pages/world: Use the resources/pages/all view instead.
  • walled_garden.js: Use the elgg/walled_garden module instead.

New API for page and action handling

Page handlers and action script files should now return an instance of \Elgg\Http\ResponseBuilder. Plugins should use the following convenience functions to build responses:

  • elgg_ok_response() sends a 2xx response with HTML (page handler) or JSON data (actions)
  • elgg_error_response() sends a 4xx or 5xx response without content/data
  • elgg_redirect_response() silently redirects the request

New API for working with file uploads

  • elgg_get_uploaded_files() - returns an array of Symfony uploaded file objects
  • ElggFile::acceptUploadedFile() - moves an uploaded file to Elgg’s filestore

New API for manipulating images

New image manipulation service implements a more efficient approach to cropping and resizing images.

  • elgg_save_resized_image() - crops and resizes an image to preferred dimensions

New API for events

  • elgg_clear_event_handlers() - similar to elgg_clear_plugin_hook_handlers this functions removes all registered event handlers

New API for signing URLs

URLs can now be signed with a SHA-256 HMAC key and validated at any time before URL expiry. This feature can be used to tokenize action URLs in email notifications, as well as other uses outside of the Elgg installation.

  • elgg_http_get_signed_url() - signs the URL with HMAC key
  • elgg_http_validate_signed_url() - validates the signed URL
  • elgg_signed_request_gatekeeper() - gatekeeper that validates the signature of the current request

Extendable form views

Form footer rendering can now be deferred until the form view and its extensions have finished rendering. This allows plugins to collaborate on form views without breaking the markup logic.

  • elgg_set_form_footer() - sets form footer for deferred rendering
  • elgg_get_form_footer() - returns currently set form footer

Metadata access_id

It’s now deprecated to create metadata with an explicit access_id value other than ACCESS_PUBLIC.

In Elgg 3.0, metadata will not be access controlled, and will be available in all contexts. If your plugin relies on access control of metadata, it would be wise to migrate storage to annotations or entities instead.

New API for extracting class names from arrays

Similar to elgg_extract(), elgg_extract_class() extracts the «class» key (if present), merges into existing class names, and always returns an array.


  • A high level 'prepare','notification' hook is now triggered for instant and subscription notifications and can be used to alter notification objects irrespective of their type.
  • 'format','notification:<method>' hook is now triggered for instant and subscription notifications and can be used to format the notification (e.g. strip HTML tags, wrap the notification body in a template etc).
  • Instant notifications are now handled by the notifications service, hence almost all hooks applicable to subscription notifications also apply to instant notifications.
  • elgg_get_notification_methods() can be used to obtain registered notification methods
  • Added ElggUser::getNotificationSettings() and ElggUser::setNotificationSetting()

Entity list functions can output tables

In functions like elgg_list_entities($options), table output is possible by setting $options['list_type'] = 'table' and providing an array of table columns as $options['columns']. Each column is an Elgg\Views\TableColumn object, usually created via methods on the service elgg()->table_columns.

Plugins can provide or alter these factory methods (see Elgg\Views\TableColumn\ColumnFactory). See the view admin/users/newest for a usage example.

Inline tabs components

Inline tabs component can now be rendered with page/components/tabs view. The components allows to switch between pre-poluated and ajax-loaded. See page/components/tabs in core views and theme_sandbox/components/tabs in developers plugin for usage instructions and examples.

API to alter registration and login URL

  • elgg_get_registration_url() should be used to obtain site’s registration URL
  • elgg_get_login_url() should be used to obtain site’s login URL
  • registration_url, site hook can be used to alter the default registration URL
  • login_url, site hook can be used to alter the default login URL

Support for fieldsets in forms

  • elgg_view_field() replaces elgg_view_input(). It has a similar API, but accepts a single array.
  • elgg_view_field() supports #type, #label, #help and #class, allowing unprefixed versions to be sent to the input view $vars.
  • The new view input/fieldset can be used to render a set of fields, each rendered with elgg_view_field().

From 2.1 to 2.2

Deprecated APIs

  • elgg.ui.river JavaScript library: Remove calls to elgg_load_js('elgg.ui.river') from plugin code. Update core/river/filter and forms/comment/save, if overwritten, to require component AMD modules
  • elgg.ui.popupOpen() and elgg.ui.popupClose() methods in elgg.ui JS library: Use elgg/popup module instead.
  • lightbox.js library: Do not use elgg_load_js('lightbox.js'); unless your code references deprecated elgg.ui.lightbox namespace. Use elgg/lightbox AMD module instead.
  • elgg.embed library and elgg.embed object: Do not use elgg_load_js('elgg.embed'). Use elgg/embed AMD module instead
  • Accessing icons_sizes config value directly: Use elgg_get_icon_sizes()
  • can_write_to_container(): Use ElggEntity::canWriteToContainer()

Deprecated Views

  • elgg/ui.river.js is deprecated: Do not rely on simplecache URLs to work.
  • groups/js is deprecated: Use groups/navigation AMD module as a menu item dependency for «feature» and «unfeature» menu items instead.
  • lightbox/settings.js is deprecated: Use getOptions, ui.lightbox JS plugin hook or data-colorbox-opts attribute.
  • elgg/ckeditor/insert.js is deprecated: You no longer need to include it, hook registration takes place in elgg/ckeditor module
  • embed/embed.js is deprecated: Use elgg/embed AMD module.

Added elgg/popup module

New elgg/popup module can be used to build out more complex trigger-popup interactions, including binding custom anchor types and opening/closing popups programmatically.

Added elgg/lightbox module

New elgg/lightbox module can be used to open and close the lightbox programmatically.

Added elgg/embed module

Even though rarely necessary, elgg/embed AMD module can be used to access the embed methods programmatically. The module bootstraps itself when necessary and is unlikely to require further decoration.

New API for handling entity icons

  • ElggEntity now implements \Elgg\EntityIcon interface
  • elgg_get_icon_sizes() - return entity type/subtype specific icon sizes
  • ElggEntity::saveIconFromUploadedFile() - creates icons from an uploaded file
  • ElggEntity::saveIconFromLocalFile() - creates icons from a local file
  • ElggEntity::saveIconFromElggFile() - creates icons from an instance of ElggFile
  • ElggEntity::getIcon() - returns an instanceof ElggIcon that points to entity icon location on filestore (this may be just a placeholder, use ElggEntity::hasIcon() to validate if file has been written)
  • ElggEntity::deleteIcon() - deletes entity icons
  • ElggEntity::getIconLastChange() - return modified time of the icon file
  • ElggEntity::hasIcon() - checks if an icon with given size has been created
  • elgg_get_embed_url() - can be used to return an embed URL for an entity’s icon (served via /serve-icon handler)

User avatars are now served via serve-file handler. Plugins should start using elgg_get_inline_url() and note that:

  • /avatar/view page handler and resource view have been deprecated
  • /mod/profile/icondirect.php file has been deprecated
  • profile_set_icon_url() is no longer registered as a callback for "entity:icon:url","user" plugin hook

Group avatars are now served via serve-file handler. Plugins should start using elgg_get_inline_url() and note that:

  • groupicon page handler (groups_icon_handler()) has been deprecated
  • /mod/groups/icon.php file has been deprecated

File entity thumbs and downloads are now served via serve-file handler. Plugins should start using elgg_get_inline_url() and elgg_get_download_url() and note that:

  • file/download page handler and resource view have been deprecated
  • mod/file/thumbnail.php file has been deprecated
  • Several views have been updated to use new download URLs, including:
    • mod/file/views/default/file/specialcontent/audio/default.php
    • mod/file/views/default/file/specialcontent/image/default.php
    • mod/file/views/default/resources/file/view.php
    • mod/file/views/rss/file/enclosure.php

Removed APIs

Just a warning that the private entity cache functions (e.g. _elgg_retrieve_cached_entity) have been removed. Some plugins may have been using them. Plugins should not use private APIs as they will more often be removed without notice.

Improved elgg/ckeditor module

elgg/ckeditor module can now be used to add WYSIWYG to a textarea programmatically with elgg/ckeditor#bind.

From 2.0 to 2.1

Deprecated APIs

  • ElggFile::setFilestore
  • get_default_filestore
  • set_default_filestore
  • elgg_get_config('siteemail'): Use elgg_get_site_entity()->email
  • URLs starting with /css/ and /js/: Use elgg_get_simplecache_url()
  • elgg.ui.widgets JavaScript object is deprecated by elgg/widgets AMD module

Application::getDb() changes

If you’re using this low-level API, do not expect it to return an Elgg\Database instance in 3.0. It now returns an Elgg\Application\Database with many deprecated. These methods were never meant to be made public API, but we will do our best to support them in 2.x.

Added elgg/widgets module

If your plugin code calls elgg.ui.widgets.init(), instead use the elgg/widgets module.

From 1.x to 2.0

Elgg can be now installed as a composer dependency instead of at document root

That means an Elgg site can look something like this:


elgg_get_root_path and $CONFIG->path will return the path to the application root directory, which is not necessarily the same as Elgg core’s root directory (which in this case is vendor/elgg/elgg/).

Do not attempt to access the core Elgg from your plugin directly, since you cannot rely on its location on the filesystem.

In particular, don’t try load engine/start.php.

// Don't do this!
dirname(__DIR__) . "/engine/start.php";

To boot Elgg manually, you can use the class Elgg\Application.

// boot Elgg in mod/myplugin/foo.php
require_once dirname(dirname(__DIR__)) . '/vendor/autoload.php';

However, use this approach sparingly. Prefer Encaminamiento instead whenever possible as that keeps your public URLs and your filesystem layout decoupled.

Also, don’t try to access the _graphics files directly.

readfile(elgg_get_root_path() . "_graphics/elgg_sprites.png");

Use Vistas instead:

echo elgg_view('elgg_sprites.png');

Cacheable views must have a file extension in their names

This requirement makes it possibile for us to serve assets directly from disk for performance, instead of serving them through PHP.

It also makes it much easier to explore the available cached resources by navigating to dataroot/views_simplecache and browsing around.

  • Bad: my/cool/template
  • Good: my/cool/template.html

We now cache assets by "$viewtype/$view", not md5("$viewtype|$view"), which can result in conflicts between cacheable views that don’t have file extensions to disambiguate files from directories.

Dropped jquery-migrate and upgraded jquery to ^2.1.4

jQuery 2.x is API-compatible with 1.x, but drops support for IE8-, which Elgg hasn’t supported for some time anyways.

See for how to move off jquery-migrate.

If you’d prefer to just add it back, you can use this code in your plugin’s init:

elgg_register_js('jquery-migrate', elgg_get_simplecache_url('jquery-migrate.js'), 'head');

Also, define a jquery-migrate.js view containing the contents of the script.

JS and CSS views have been moved out of the js/ and css/ directories

They also have been given .js and .css extensions respectively if they didn’t already have them:

Old view New view
js/view view.js
js/other.js other.js
css/view view.css
css/other.css other.css
js/img.png img.png

The main benefit this brings is being able to co-locate related assets. So a template (view.php) can have its CSS/JS dependencies right next to it (view.css, view.js).

Care has been taken to make this change as backwards-compatible as possible, so you should not need to update any view references right away. However, you are certainly encouraged to move your JS and CSS views to their new, canonical locations.

Practically speaking, this carries a few gotchas:

The view_vars, $view_name and view, $view_name hooks will operate on the canonical view name:

elgg_register_plugin_hook_handler('view', 'css/elgg', function($hook, $view_name) {
  assert($view_name == 'elgg.css') // not "css/elgg"

Using the view, all hook and checking for individual views may not work as intended:

elgg_register_plugin_hook_handler('view', 'all', function($hook, $view_name) {
  // Won't work because "css/elgg" was aliased to "elgg.css"
  if ($view_name == 'css/elgg') {
    // Never executed...

  // Won't work because no canonical views start with css/* anymore
  if (strpos($view_name, 'css/') === 0) {
    // Never executed...

Please let us know about any other BC issues this change causes. We’d like to fix as many as possible to make the transition smooth.

fxp/composer-asset-plugin is now required to install Elgg from source

We use fxp/composer-asset-plugin to manage our browser assets (js, css, html) with Composer, but it must be installed globally before installing Elgg in order for the bower-asset/* packages to be recognized. To install it, run:

composer global require fxp/composer-asset-plugin

If you don’t do this before running composer install or composer create-project, you will get an error message:

Package fxp/composer-asset-plugin not found

List of deprecated views and view arguments that have been removed

We dropped support for and/or removed the following views:

  • canvas/layouts/*
  • categories
  • categories/view
  • core/settings/tools
  • embed/addcontentjs
  • footer/analytics (Use page/elements/foot instead)
  • groups/left_column
  • groups/right_column
  • groups/search/finishblurb
  • groups/search/startblurb
  • input/calendar (Use input/date instead)
  • input/datepicker (Use input/date instead)
  • input/pulldown (Use input/select instead)
  • invitefriends/formitems
  • js/admin (Use AMD and elgg_require_js instead of extending JS views)
  • js/initialise_elgg (Use AMD and elgg_require_js instead of extending JS views)
  • members/nav
  • metatags (Use the “head”, “page” plugin hook instead)
  • navigation/topbar_tools
  • navigation/viewtype
  • notifications/subscriptions/groupsform
  • object/groupforumtopic
  • output/calendar (Use output/date instead)
  • output/confirmlink (Use output/url instead)
  • page_elements/contentwrapper
  • page/elements/shortcut_icon (Use the “head”, “page” plugin hook instead)
  • page/elements/wrapper
  • profile/icon (Use elgg_get_entity_icon)
  • river/object/groupforumtopic/create
  • settings/{plugin}/edit (Use plugins/{plugin}/settings instead)
  • user/search/finishblurb
  • user/search/startblurb
  • usersettings/{plugin}/edit (Use plugins/{plugin}/usersettings instead)
  • widgets/{handler}/view (Use widgets/{handler}/content instead)

We also dropped the following arguments to views:

  • «value» in output/iframe (Use «src» instead)
  • «area2» and «area3» in page/elements/sidebar (Use «sidebar» or view extension instead)
  • «js» in icon views (e.g. icon/user/default)
  • «options» to input/radio and input/checkboxes which aren’t key-value pairs will no longer be acceptable.

All scripts moved to bottom of page

You should test your plugin with the JavaScript error console visible. For performance reasons, Elgg no longer supports script elements in the head element or in HTML views. elgg_register_js will now load all scripts at the end of the body element.

You must convert inline scripts to AMD or to external scripts loaded with elgg_load_js.

Early in the page, Elgg provides a shim of the RequireJS require() function that simply queues code until the AMD elgg and jQuery modules are defined. This provides a straightforward way to convert many inline scripts to use require().

Inline code which will fail because the stack is not yet loaded:

$(function () {
    // code using $ and elgg

This should work in Elgg 2.0:

require(['elgg', 'jquery'], function (elgg, $) {
    $(function () {
        // code using $ and elgg

Attribute formatter removes keys with underscores

elgg_format_attributes() (and all APIs that use it) now filter out attributes whose name contains an underscore. If the attribute begins with data-, however, it will not be removed.

Callbacks in Queries

Make sure to use only valid callable values for «callback» argument/options in the API.

Querying functions will now will throw a RuntimeException if is_callable() returns false for the given callback value. This includes functions such as elgg_get_entities(), get_data(), and many more.

Comments plugin hook

Plugins can now return an empty string from 'comments',$entity_type hook in order to override the default comments component view. To force the default comments component, your plugin must return false. If you were using empty strings to force the default comments view, you need to update your hook handlers to return false.

Container permissions hook

The behavior of the container_permissions_check hook has changed when an entity is being created: Before 2.0, the hook would be called twice if the entity’s container was not the owner. On the first call, the entity’s owner would be passed in as $params['container'], which could confuse handlers.

In 2.0, when an entity is created in a container like a group, if the owner is the same as the logged in user (almost always the case), this first check is bypassed. So the container_permissions_check hook will almost always be called once with $params['container'] being the correct container of the entity.

Creating or deleting a relationship triggers only one event

The «create» and «delete» relationship events are now only fired once, with "relationship" as the object type.

E.g. Listening for the "create", "member" or "delete", "member" event(s) will no longer capture group membership additions/removals. Use the "create", "relationship" or "delete", "relationship" events.

Discussion feature has been pulled from groups into its own plugin

The object, groupforumtopic subtype has been replaced with the object, discussion subtype. If your plugin is using or altering the old discussion feature, you should upgrade it to use the new subtype.

Nothing changes from the group owners” point of view. The discussion feature is still available as a group tool and all old discussions are intact.

Dropped login-over-https feature

For the best security and performance, serve all pages over HTTPS by switching the scheme in your site’s wwwroot to https at http://yoursite.tld/admin/settings/advanced

Elgg has migrated from ext/mysql to PDO MySQL

Elgg now uses a PDO_MYSQL connection and no longer uses any ext/mysql functions. If you use mysql_* functions, implicitly relying on an open connection, these will fail.

If your code uses one of the following functions, read below.

  • execute_delayed_write_query()
  • execute_delayed_read_query()

If you provide a callable $handler to be called with the results, your handler will now receive a \Doctrine\DBAL\Driver\Statement object. Formerly this was an ext/mysql result resource.

Event/Hook calling order may change

When registering for events/hooks, the all keyword for wildcard matching no longer has any effect on the order that handlers are called. To ensure your handler is called last, you must give it the highest priority of all matching handlers, or to ensure your handler is called first, you must give it the lowest priority of all matching handlers.

If handlers were registered with the same priority, these are called in the order they were registered.

To emulate prior behavior, Elgg core handlers registered with the all keyword have been raised in priority. Some of these handlers will most likely be called in a different order.

export/ URLs are no longer available

Elgg no longer provides this endpoint for exposing resource data.

Icons migrated to Font Awesome

Elgg’s sprites and most of the CSS classes beginning with elgg-icon- have been removed.

Usage of elgg_view_icon() is backward compatible, but static HTML using the elgg-icon classes will have to be updated to the new markup.

Increase of z-index value in elgg-menu-site class

The value of z-index in the elgg-menu-site class has been increased from 1 to 50 to allow for page elements in the content area to use the z-index property without the «More» site menu’s dropdown being displayed behind these elements. If your plugin/theme overrides the elgg-menu-site class or views/default/elements/navigation.css please adjust the z-index value in your modified CSS file accordingly.

input/autocomplete view

Plugins that override the input/autocomplete view will need to include the source URL in the data-source attribute of the input element, require the new elgg/autocomplete AMD module, and call its init method. The 1.x javascript library elgg.autocomplete is no longer used.

Introduced third-party library for sending email

We are using the excellent Zend\Mail library to send emails in Elgg 2.0. There are likely edge cases that the library handles differently than Elgg 1.x. Take care to test your email notifications carefully when upgrading to 2.0.

Label elements

The following views received label elements around some of the input fields. If your plugin/theme overrides these views please check for the new content.

  • views/default/core/river/filter.php
  • views/default/forms/admin/plugins/filter.php
  • views/default/forms/admin/plugins/sort.php
  • views/default/forms/login.php

Plugin Aalborg Theme

The view page/elements/navbar now uses a Font Awesome icon for the mobile menu selector instead of an image. The bars.png image and supporting CSS for the 1.12 rendering has been removed, so update your theme accordingly.

Plugin Likes

Objects are no longer likable by default. To support liking, you can register a handler to permit the annotation, or more simply register for the hook ["likes:is_likable", "<type>:<subtype>"] and return true. E.g.

elgg_register_plugin_hook_handler('likes:is_likable', 'object:mysubtype', 'Elgg\Values::getTrue');

Just as before, the permissions_check:annotate hook is still called and may be used to override default behavior.

Plugin Messages

If you’ve removed or replaced the handler function messages_notifier to hide/alter the inbox icon, you’ll instead need to do the same for the topbar menu handler messages_register_topbar. messages_notifier is no longer used to add the menu link.

Messages will no longer get the metadata “msg” for newly created messages. This means you can not rely on that metadata to exist.

Plugin Blog

The blog pages showing “Mine” or “Friends” listings of blogs have been changed to list all the blogs owned by the users (including those created in groups).

Plugin Bookmarks

The bookmark pages showing “Mine” or “Friends” listings of bookmarks have been changed to list all the bookmarks owned by the users (including those created in groups).

Plugin File

The file pages showing “Mine” or “Friends” listings of files have been changed to list all the files owned by the users (including those created in groups).

Removed Classes

  • ElggInspector
  • Notable
  • FilePluginFile: replace with ElggFile (or load with get_entity())

Removed keys available via elgg_get_config()

  • allowed_ajax_views
  • dataroot_in_settings
  • externals
  • externals_map
  • i18n_loaded_from_cache
  • language_paths
  • pagesetupdone
  • registered_tag_metadata_names
  • simplecache_enabled_in_settings
  • translations
  • viewpath
  • views
  • view_path
  • viewtype
  • wordblacklist

Also note that plugins should not be accessing the global $CONFIG variable except for in settings.php.

Removed Functions

  • blog_get_page_content_friends
  • blog_get_page_content_read
  • count_unread_messages()
  • delete_entities()
  • delete_object_entity()
  • delete_user_entity()
  • elgg_get_view_location()
  • elgg_validate_action_url()
  • execute_delayed_query()
  • extend_view()
  • get_db_error()
  • get_db_link()
  • get_entities()
  • get_entities_from_access_id()
  • get_entities_from_access_collection()
  • get_entities_from_annotations()
  • get_entities_from_metadata()
  • get_entities_from_metadata_multi()
  • get_entities_from_relationship()
  • get_filetype_cloud()
  • get_library_files()
  • get_views()
  • is_ip_in_array()
  • list_entities()
  • list_entities_from_annotations()
  • list_group_search()
  • list_registered_entities()
  • list_user_search()
  • load_plugins()
  • menu_item()
  • make_register_object()
  • mysql_*(): Elgg no longer uses ext/mysql
  • remove_blacklist()
  • search_for_group()
  • search_for_object()
  • search_for_site()
  • search_for_user()
  • search_list_objects_by_name()
  • search_list_groups_by_name()
  • search_list_users_by_name()
  • set_template_handler()
  • test_ip()

Removed methods

  • ElggCache::set_variable()
  • ElggCache::get_variable()
  • ElggData::initialise_attributes()
  • ElggData::getObjectOwnerGUID()
  • ElggDiskFilestore::make_directory_root()
  • ElggDiskFilestore::make_file_matrix()
  • ElggDiskFilestore::user_file_matrix()
  • ElggDiskFilestore::mb_str_split()
  • ElggEntity::clearMetadata()
  • ElggEntity::clearRelationships()
  • ElggEntity::clearAnnotations()
  • ElggEntity::getOwner()
  • ElggEntity::setContainer()
  • ElggEntity::getContainer()
  • ElggEntity::getIcon()
  • ElggEntity::setIcon()
  • ElggExtender::getOwner()
  • ElggFileCache::create_file()
  • ElggObject::addToSite(): parent function in ElggEntity still available
  • ElggObject::getSites(): parent function in ElggEntity still available
  • ElggSite::getCollections()
  • ElggUser::addToSite(): parent function in ElggEntity still available
  • ElggUser::getCollections()
  • ElggUser::getOwner()
  • ElggUser::getSites(): parent function in ElggEntity still available
  • ElggUser::listFriends()
  • ElggUser::listGroups()
  • ElggUser::removeFromSite(): parent function in ElggEntity still available

The following arguments have also been dropped:

  • ElggSite::getMembers() - 2: $offset
  • elgg_view_entity_list() - 3: $offset - 4: $limit - 5: $full_view - 6: $list_type_toggle - 7: $pagination

Removed Plugin Hooks

Removed Actions

  • widgets/upgrade

Removed Views

  • forms/admin/plugins/change_state

Removed View Variables

During rendering, the view system no longer injects these into the scope:

  • $vars['url']: replace with elgg_get_site_url()
  • $vars['user']: replace with elgg_get_logged_in_user_entity()
  • $vars['config']: use elgg_get_config() and elgg_set_config()
  • $CONFIG: use elgg_get_config() and elgg_set_config()

Also several workarounds for very old views are no longer performed. Make these changes:

  • Set $vars['full_view'] instead of $vars['full'].
  • Set $vars['name'] instead of $vars['internalname'].
  • Set $vars['id'] instead of $vars['internalid'].

Removed libraries

  • elgg:markdown: Elgg no longer provides a markdown implementation. You must provide your own.

Specifying View via Properties

The metadata $entity->view no longer specifies the view used to render in elgg_view_entity().

Similarly the property $annotation->view no longer has an effect within elgg_view_annotation().

Viewtype is static after the initial elgg_get_viewtype() call

elgg_set_viewtype() must be used to set the viewtype at runtime. Although Elgg still checks the view input and $CONFIG->view initially, this is only done once per request.


It’s deprecated to read or write to metadata keys starting with filestore:: on ElggFile objects. In Elgg 3.0 this metadata will be deleted if it points to the current data root path, so few file objects will have it. Plugins should only use ElggFile::setFilestore if files need to be stored in a custom location.


This is not the only deprecation in Elgg 2.0. Plugin developers should watch their site error logs.

From 1.10 to 1.11

Comment highlighting

If your theme is using the file views/default/css/elements/components.php, you must add the following style definitions in it to enable highlighting for comments and discussion replies:

.elgg-comments .elgg-state-highlight {
        -webkit-animation: comment-highlight 5s;
        animation: comment-highlight 5s;
@-webkit-keyframes comment-highlight {
        from {background: #dff2ff;}
        to {background: white;}
@keyframes comment-highlight {
        from {background: #dff2ff;}
        to {background: white;}

From 1.9 to 1.10

File uploads

If your plugin is using a snippet copied from the file/upload action to fix detected mime types for Microsoft zipped formats, it can now be safely removed.

If your upload action performs other manipulations on detected mime and simple types, it is recommended to make use of available plugin hooks:

  • 'mime_type','file' for filtering detected mime types
  • 'simple_type','file' for filtering parsed simple types

De la versión 1.8 a la 1.9

En los ejemplos estamos actualizando un complemento imaginario, «Photos» (fotos).

Sólo se incluyen los cambios fundamentales. Por ejemplo, algunas de las funciones que están ahora obsoletas no se mencionan en esta sección.

Cada sección incluirá información sobre si el cambio es compatible hacia atrás con la versión 1.8 de Elgg.

El fichero «manifest»

Si su complemento es compatible con la versión 1.8 de Elgg, no necesita hacer ningún cambio en este fichero.

De todas formas, se recomienda añadir la etiqueta <id>. Su valor debería ser el nombre de la carpeta que contiene el complemento dentro de la carpeta mod/.

Si hace cambios que hacen el complemento incompatible con versiones anteriores con las que antes sí era compatible, debe actualizar la versión del complemento y la versión requerida de Elgg.

Ejemplo (resumido) de la versión anterior:

<?xml version="1.0" encoding="UTF-8"?>
<plugin_manifest xmlns="">
    <author>John Doe</author>
    <description>Adds possibility to upload photos and arrange them into albums.</description>

Ejemplo (resumido) de la nueva versión:

<?xml version="1.0" encoding="UTF-8"?>
<plugin_manifest xmlns="">
    <author>John Doe</author>
    <description>Adds possibility to upload photos and arrange them into albums.</description>

$CONFIG y $vars[“config”]

Tanto la variable global $CONFIG como el parámetro $vars['config'] están obsoletos. Deberían substituirse por la función elgg_get_config().

Ejemplo de código de la versión anterior:

// Using the global $CONFIG variable:
global $CONFIG;
$plugins_path = $CONFIG->plugins_path

// Using the $vars view parameter:
$plugins_path = $vars['plugins_path'];

Ejemplo de código de la nueva versión:

$plugins_path = elgg_get_config('plugins_path');


Compatible con la versión 1.8.


Así se actualizó el complemento «community_plugins»:

Ficheros de idioma

En la versión 1.8 de Elgg, los ficheros de idioma necesitaban usar la función add_translation(). A partir de la versión 1.9, basta con devolver el vector que previamente se pasó a la función como parámetro. El núcleo de Elgg se basará en el nombre del fichero (por ejemplo: «es.php») para determinar qué idioma contiene el fichero.

Ejemplo del método anterior en languages/en.php:

$english = array(
    'photos:all' => 'All photos',
add_translation('en', $english);

Ejemplo del nuevo método:

return array(
    'photos:all' => 'All photos',


No es compatible con la versión 1.8.


Uno de los cambios más importantes en la versión 1.9 de Elgg es el del sistema de notificaciones. El nuevo sistema de notificaciones ofrece formas más flexibles y escalables de enviar notificaciones.

Ejemplo del método anterior:

function photos_init() {
    // Tell core that we want to send notifications about new photos
    register_notification_object('object', 'photo', elgg_echo('photo:new'));

    // Register a handler that creates the notification message
    elgg_register_plugin_hook_handler('notify:entity:message', 'object', 'photos_notify_message');

 * Set the notification message body
 * @param string $hook    Hook name
 * @param string $type    Hook type
 * @param string $message The current message body
 * @param array  $params  Parameters about the photo
 * @return string
function photos_notify_message($hook, $type, $message, $params) {
    $entity = $params['entity'];
    $to_entity = $params['to_entity'];
    $method = $params['method'];
    if (elgg_instanceof($entity, 'object', 'photo')) {
        $descr = $entity->excerpt;
        $title = $entity->title;
        $owner = $entity->getOwnerEntity();
        return elgg_echo('photos:notification', array(
    return null;

Ejemplo del nuevo método:

function photos_init() {
    elgg_register_notification_event('object', 'photo', array('create'));
    elgg_register_plugin_hook_handler('prepare', 'notification:publish:object:photo', 'photos_prepare_notification');

 * Prepare a notification message about a new photo
 * @param string                          $hook         Hook name
 * @param string                          $type         Hook type
 * @param Elgg_Notifications_Notification $notification The notification to prepare
 * @param array                           $params       Hook parameters
 * @return Elgg_Notifications_Notification
function photos_prepare_notification($hook, $type, $notification, $params) {
    $entity = $params['event']->getObject();
    $owner = $params['event']->getActor();
    $recipient = $params['recipient'];
    $language = $params['language'];
    $method = $params['method'];

    // Title for the notification
    $notification->subject = elgg_echo('photos:notify:subject', array($entity->title), $language);

    // Message body for the notification
    $notification->body = elgg_echo('photos:notify:body', array(
    ), $language);

    // The summary text is used e.g. by the site_notifications plugin
    $notification->summary = elgg_echo('photos:notify:summary', array($entity->title), $language);

    return $notification;


No es compatible con la versión 1.8.


Así se actualizó el complemento «community_plugins» para usar el nuevo sistema:

Notifications can also be sent with the notify_user() function.

It has however been updated to support three new optional parameters passed inside an array as the fifth parameter.

The parameters give notification plugins more control over the notifications, so they should be included whenever possible. For example the bundled site_notifications plugin won’t work properly if the parameters are missing.


  • object The object that we are notifying about (e.g. ElggEntity or ElggAnnotation). This is needed so that notification plugins can provide a link to the object.
  • action String that describes the action that triggered the notification (e.g. «create», «update», etc).
  • summary String that contains a summary of the notification. (It should be more informative than the notification subject but less informative than the notification body.)

Ejemplo del método anterior:

// Notify $owner that $user has added a $rating to an $entity created by him

$subject = elgg_echo('rating:notify:subject');
$body = elgg_echo('rating:notify:body', array(


Ejemplo del nuevo método:

// Notify $owner that $user has added a $rating to an $entity created by him

$subject = elgg_echo('rating:notify:subject');
$summary = elgg_echo('rating:notify:summary', array($entity->title));
$body = elgg_echo('rating:notify:body', array(

$params = array(
        'object' => $rating,
        'action' => 'create',
        'summary' => $summary,



Compatible con la versión 1.8.

Añadir elementos a la lista de actividad

add_to_river('river/object/photo/create', 'create', $user_guid, $photo_guid);
    'view' => 'river/object/photo/create',
    'action_type' => 'create',
    'subject_guid' => $user_guid,
    'object_guid' => $photo_guid,

También puede hacer uso del parámetro opcional target_guid para indicar el destinatario de la acción de crear.

Por ejemplo, si la foto se pretendiese añadir a un álbum de fotos, se haría pasándole también:

'target_guid' => $album_guid,


No es compatible con la versión 1.8.

Gestores de direcciones URL de entidades

La función elgg_register_entity_url_handler() ha pasado a estar obsoleta en la versión 1.9 de Elgg, donde se recomienda usar el gancho de complementos 'entity:url', 'object' en us lugar.

Ejemplo del método anterior:

 * Initialize the photo plugin
my_plugin_init() {
    elgg_register_entity_url_handler('object', 'photo', 'photo_url_handler');

 * Returns the URL from a photo entity
 * @param ElggEntity $entity
 * @return string
function photo_url_handler($entity) {
    return "photo/view/{$entity->guid}";

Ejemplo del nuevo método:

 * Initialize the photo plugin
my_plugin_init() {
    elgg_register_plugin_hook_handler('entity:url', 'object', 'photo_url_handler');

 * Returns the URL from a photo entity
 * @param string $hook   'entity:url'
 * @param string $type   'object'
 * @param string $url    The current URL
 * @param array  $params Hook parameters
 * @return string
function photo_url_handler($hook, $type, $url, $params) {
    $entity = $params['entity'];

    // Check that the entity is a photo object
    if ($entity->getSubtype() !== 'photo') {
        // This is not a photo object, so there's no need to go further

    return "photo/view/{$entity->guid}";


No es compatible con la versión 1.8.

Servicios web

In Elgg 1.8 the web services API was included in core and methods were exposed using expose_function(). To enable the same functionality for Elgg 1.9, enable the «Web services 1.9» plugin and replace all calls to expose_function() with elgg_ws_expose_function().

De la versión 1.7 a la 1.8

La versión 1.8 ha sido el mayor salto en el desarrollo de Elgg desde la versión 1.0. Es por ello que para actualizar el núcleo de Elgg y sus complementos hace falta más trabajo que en anteriores actualizaciones. Se produjeron algunos cambios pequeños en la API, y siguiendo con nuestra práctica habitual, los métodos que pasaron a quedar obsoletos se actualizaron para funcionar con la nueva API. Los cambios más importantes afectaron a la estandarización de complementos y al sistema de vistas.

Actualizar el núcleo

Elimine las siguientes carpetas (se encuentran en el mismo nivel que «_graphics» o «engine»):

  • _css
  • account
  • admin
  • dashboard
  • entities
  • friends
  • search
  • settings
  • simplecache
  • views


Tendrá problemas si no elimina estas carpetas antes de actualizar.

Actualizar complementos

Use encaminamientos estándar con gestores de páginas

  • Todo: /page_handler/all
  • Contenido del usuario: /page_handler/owner/:username
  • Contenido de contactos del usuario: /page_handler/friends/:username
  • Entidad suelta: /page_handler/view/:guid/:title
  • Añadido: /page_handler/add/:container_guid
  • Edición: /page_handler/edit/:guid
  • Lista de grupos: /page_handler/group/:guid/all

Incluya scripts de gestión de páginas desde el gestor de páginas

Casi todos los gestores de páginas deberían tener un script de gestión de páginas. Por ejemplo, bookmarks/all => mod/bookmarks/pages/bookmarks/all.php.

  • Llame a set_input() para identificadores de entidades en el gestor de páginas y use get_input() en los scripts de gestión de páginas.
  • Llame a gatekeeper() y a admin_gatekeeper() en la función del gestor de páginas si fuese necesario.
  • La dirección URL del grupo debería usar el script pages/:handler/owner.php.
  • Los gestores de páginas no deberían contener HTML.
  • Actualice las direcciones URL en todo el complemento. No se olvide de eliminar /pg/.

Use gestores de páginas y scripts estandarizados

  • Guarde los scripts de gestión de páginas en mod/:plugin/pages/:page_handler/:page_name.php

  • Use la disposición de página del contenido en los scripts de gestión de páginas:

    $content = elgg_view_layout('content', $options);
  • Los scripts de gestión de páginas no deberían contener HTML.

  • Llame a elgg_push_breadcrumb() en los scripts de gestión de páginas.

  • No es necesario definir el dueño de una página si las direcciones URL están en el formato estándar.

  • Para el contenido de grupos, compruebe el identificador del contenedor (container_guid) mediante la función elgg_get_page_owner_entity().

La vista object/:subtype

  • Asegúrese de que hay vistas para $vars['full_view'] == true y $vars['full_view'] == false. $vars['full_view'] ha substituido a $vars['full].
  • Compruebe el objeto en $vars['entity']. Use elgg_instance_of() para asegurarse de que se trata de el tipo de entidad que busca.
  • Devuelva true para cancelar la vista directamente si falta la entidad o ésta no es correcta.
  • Use elgg_view(‘object/elements/summary’, array(‘entity’ => $entity)); y elgg_view_menu(‘entity’, array(‘entity’ => $entity)); como ayuda para dar formato. Debería usar poco o ningún lenguaje de etiquetas en estas vistas.

Actualizar la estructura de las acciones

  • Use espacios de nombre para ficheros y nombres de acciones. Por ejemplo, mod/blog/actions/blog/save.phpaction/blog/save.
  • Use las siguientes direcciones URL de acciones:
    • Añadir: action/:plugin/save.
    • Editar: action/:plugin/save.
    • Eliminar: action/:plugin/delete.
  • Haga que la acción de eliminar acepte action/:handler/delete?guid=:guid de forma que el menú de entidades de metadatos tenga la dirección URL correcta de manera predeterminada.

Actualice las funciones que se hayan quedado obsoletas

  • Las funciones marcadas como obsoletas en la versión 1.7 de Elgg producen errores visibles en la versión 1.8.
  • También puede actualizar funciones que se marcaron como obsoletas en la versión 1.8.
    • A muchas funciones de registro simplemente se les añadió el prefijo elgg_ por motivos de consistencia, y actualizarlas no debería ser difícil.
    • Véase la lista completa en /engine/lib/deprecated-1.8.php.
    • Puede cambiar el nivel de depuración a «warning» (aviso) para recibir de manera visual recordatorios sobre el uso de funciones obsoletas.

Actualice las vistas de artilugios

Puede tomar como ejemplos los artilugios de blogs o de ficheros.

Actualice el módulo de perfiles de grupos

Use los complementos de blogs y de ficheros a modo de ejemplo. Le ayudarán a hacer posible cambiar el tema del complemento usando la nueva infraestructura CSS.

Actualice los formularios

  • Mueva los cuerpos de los formularios a la vista forms/:action para usar el nuevo elgg_view_form de Evan.
  • Use las vistas de introducción de datos en los cuerpos de los formularios en vez de usar HTML. Esto ayudará a que el complemento sea compatible con los temas, y a que sea más fácil de mantener ante cambios futuros.
  • Añada una función que prepare el formulario. A modo de ejemplo, véase mod/file/lib/file.php.
  • Persista los formularios. A modo de ejemplo, véanse la acción de enviar (upload) del complemento de ficheros y su función para preparar el formulario.

La API de los formularios se describe con más detalle en Formularios y acciones.

Haz limpieza de CSS y HTML

Se han añadido muchos patrones de CSS al fichero CSS base (módulos, bloques de imágenes, primitivas de espaciado). Se recomienda usar dichos patrones y clases siempre que sea posible. De esa forma:

  1. Se reducen los costes de mantenimiento, puesto que puede eliminar la mayor parte de su código CSS personalizado.
  2. Su complemento es más compatible con los temas de la comunidad.

Si necesita mucho código CSS, busque patrones que podrían añadirse al núcleo de Elgg.

Usamos guiones en vez de guiones bajos en las clases e identificadores, y le recomendamos que haga lo mismo por consistencia.

Si de verdad necesita su propio CSS, debería usar si propio espacio de nombres, uno distinto de elgg-.

Actualice el fichero manifest.xml

  • Use para automatizar la tarea.
  • No utilice la categoría «bundled» (de serie) en sus complementos. Esa categoría corresponde sólo a complementos distribuidos junto con Elgg.

Actualice las vistas de configuración global y de usuario

  • La vista de configuración ha pasado a ser plugins/:plugin/settings (antes era settings/:plugin/edit).
  • La vista de configuración de usuario ha pasado a ser plugins/:plugin/usersettings (antes era usersettings/:plugin/edit).