Contents
- PHP 7.0 is now required
$CONFIG
is removed!- Removed views
- Removed functions/methods
- Deprecated APIs
- Removed global vars
- Removed classes/interfaces
- Schema changes
- Changes in
elgg_get_entities
,elgg_get_metadata
andelgg_get_annotations
getter functions - Boolean entity properties
- Metadata Changes
- Permissions and Access
- Multi Site Changes
- Entity Subtable Changes
- Friends and Group Access Collection
- Subtypes no longer have an ID
- Custom class loading
- Dependency Injection Container
- Search changes
- Form and field related changes
- Entity and River Menu Changes
- Removed libraries
- Removed pagehandling
- Removed actions
- Inheritance changes
- Removed JavaScript APIs
- Removed hooks/events
- Removed forms/actions
- APIs that now accept only an
$options
array - Plugin functions that now require an explicit
$plugin_id
- Class constructors that now accept only a
stdClass
object ornull
- Miscellaneous API changes
- View extension behaviour changed
- JavaScript hook calling order may change
- Widget layout related changes
- Routing
- Labelling
- Request value filtering
- Action responses
- HtmLawed is no longer a plugin
- New approach to page layouts
- Likes plugin
- Notifications plugin
- Pages plugin
- Profile plugin
- Data Views plugin
- Twitter API plugin
- Legacy URLs plugin
- User validation by email plugin
- Email delivery
- Theme and styling changes
- Comments
- Object listing views
- Menu changes
- Entity icons
- Icon glyphs
- Autocomplete (user and friends pickers)
- Friends collections
- Layout of
.elgg-body
elements - Delete river items
- Discussion replies moved to comments
- Translations cleanup
- System Log
- Error logging
- Composer asset plugin no longer required
- Cron logs
- Removed / changed language keys
- New MySQL schema features are not applied
- Miscellaneous changes
- Twitter API plugin
- Unit and Integration Testing
5.6 is reaching it's end of life. PHP 7.0 is now required to install and run Elgg.
Not exactly, however you must audit its usage and should replace it with elgg_get_config()
and elgg_set_config()
, as recommended since Elgg 1.9.
The global $CONFIG
is now a proxy for Elgg's configuration container, and modifications will fail if you try to alter array properties directly. E.g. $CONFIG->cool_fruit[] = 'Pear';
. The silver lining is that failures will emit NOTICEs.
forms/account/settings
: usersettings extension can now extend the viewforms/usersettings/save
forms/admin/site/advanced/system
resources/file/download
output/checkboxes
: useoutput/tags
if you want the same behaviourinput/write_access
: mod/pages now uses the access:collections:write plugin hook.invitefriends/form
page/layouts/content
: usepage/layouts/default
page/layouts/one_column
: usepage/layouts/default
page/layouts/one_sidebar
: usepage/layouts/default
page/layouts/two_sidebar
: usepage/layouts/default
page/layouts/walled_garden
: usepage/layouts/default
page/layouts/walled_garden/cancel_button
page/layouts/two_column_left_sidebar
page/layouts/widgets/add_panel
page/elements/topbar_wrapper
: update your use ofpage/elements/topbar
to include a check for a logged in userpages/icon
groups/group_sort_menu
: useregister, filter:menu:groups/all
plugin hookgroups/my_status
groups/profile/stats
subscriptions/form/additions
: extendnotifications/settings/other
insteadlikes/count
: modifications can now be done to thelikes_count
menu itemlikes/css
: likes now useselgg/likes.css
resources/members/index
messageboard/css
notifications/subscriptions/personal
notifications/subscriptions/collections
notifications/subscriptions/form
notifications/subscriptions/jsfuncs
notifications/subscriptions/forminternals
notifications/css
pages/input/parent
river/item
: use elgg_view_river_item() to render river itemsriver/user/default/profileupdate
admin.js
aalborg_theme/homepage.png
aalborg_theme/css
resources/avatar/view
: Use entity icon APIajax_loader.gif
button_background.gif
button_graduation.png
elgg_toolbar_logo.gif
header_shadow.png
powered_by_elgg_badge_drk_bckgnd.gif
powered_by_elgg_badge_light_bckgnd.gif
sidebar_background.gif
spacer.gif
toptoolbar_background.gif
two_sidebar_background.gif
ajax_loader_bw.gif
: usegraphics/ajax_loader_bw.gif
elgg_logo.png
: usegraphics/elgg_logo.png
favicon-128.png
: usegraphics/favicon-128.png
favicon-16.png
: usegraphics/favicon-16.png
favicon-32.png
: usegraphics/favicon-32.png
favicon-64.png
: usegraphics/favicon-64.png
favicon.ico
: usegraphics/favicon.ico
favicon.svg
: usegraphics/favicon.svg
friendspicker.png
: usegraphics/friendspicker.png
walled_garden.jpg
: usegraphics/walled_garden.jpg
core/friends/collection
core/friends/collections
core/friends/collectiontabs
core/friends/tablelist
core/friends/talbelistcountupdate
lightbox/elgg-colorbox-theme/colorbox-images/*`
navigation/menu/page
: now usesnavigation/menu/default
and a prepare hooknavigation/menu/site
: now uses default viewpage/elements/by_line
: Useobject/elements/imprint
forms/admin/site/advanced/security
: the site secret information has been moved toforms/admin/security/settings
river/object/file/create
: check :doc:`/guides/river`river/object/page/create
: check :doc:`/guides/river`river/object/page_top/create
: check :doc:`/guides/river`river/relationship/member
: check :doc:`/guides/river`object/page_top
: useobject/page
ajax/discussion/reply/edit
: See :ref:`upgrade-discussion-replies`discussion/replies
: See :ref:`upgrade-discussion-replies`object/discussion_reply
: See :ref:`upgrade-discussion-replies`resources/discussion/reply/edit
: See :ref:`upgrade-discussion-replies`resources/elements/discussion_replies
: See :ref:`upgrade-discussion-replies`river/elements/discussion_replies
: See :ref:`upgrade-discussion-replies`river/object/discussion/create
river/object/discussion_reply/create
: See :ref:`upgrade-discussion-replies`search/object/discussion_reply/entity
: See :ref:`upgrade-discussion-replies`rss/discussion/replies
: See :ref:`upgrade-discussion-replies`search/header
search/layout
in bothdefault
andrss
viewtypessearch/no_results
search/object/comment/entity
search/css
: Moved tosearch/search.css
search/startblurb
bookmarks/bookmarklet.gif
blog_get_page_content_list
blog_get_page_content_archive
blog_get_page_content_edit
forms/invitefriends/invite
: useforms/friends/invite
resources/invitefriends/invite
: useresources/friends/invite
resources/reportedcontent/add
resources/reportedcontent/add_form
resources/site_notifications/view
: Useresources/site_notifications/owner
resources/site_notifications/everyone
: Useresources/site_notifications/all
All the functions in engine/lib/deprecated-1.9.php
were removed. See https://github.com/Elgg/Elgg/blob/2.0/engine/lib/deprecated-1.9.php for these functions. Each @deprecated
declaration includes instructions on what to use instead.
All the functions in engine/lib/deprecated-1.10.php
were removed. See https://github.com/Elgg/Elgg/blob/2.0/engine/lib/deprecated-1.10.php for these functions. Each @deprecated
declaration includes instructions on what to use instead.
elgg_register_library
: require your library files so they are available globally to other pluginselgg_load_library
activity_profile_menu
can_write_to_container
: UseElggEntity->canWriteToContainer()
create_metadata_from_array
metadata_array_to_values
datalist_get
datalist_set
detect_extender_valuetype
developers_setup_menu
elgg_disable_metadata
elgg_enable_metadata
elgg_get_class_loader
elgg_get_metastring_id
elgg_get_metastring_map
elgg_register_class
elgg_register_classes
elgg_register_viewtype
elgg_is_registered_viewtype
file_delete
: UseElggFile->deleteIcon()
file_get_type_cloud
file_type_cloud_get_url
get_default_filestore
get_site_entity_as_row
get_group_entity_as_row
get_missing_language_keys
get_object_entity_as_row
get_user_entity_as_row
update_river_access_by_object
garbagecollector_orphaned_metastrings
groups_access_collection_override
groups_get_group_tool_options
: Useelgg()->group_tools->all()
groups_join_group
: UseElggGroup::join
groups_prepare_profile_buttons
: Useregister, menu:title
hookgroups_register_profile_buttons
: Useregister, menu:title
hookgroups_setup_sidebar_menus
groups_set_icon_url
groups_setup_sidebar_menus
messages_notification_msg
set_default_filestore
generate_user_password
: UseElggUser::setPassword
row_to_elggrelationship
run_function_once
: UseElgg\Upgrade\Batch
interfacesystem_messages
notifications_plugin_pagesetup
elgg_format_url
: Use elgg_format_element() or the "output/text" view for HTML escaping.get_site_by_url
elgg_override_permissions
: No longer used as handler forpermissions_check
andcontainer_permissions_check
hookselgg_check_access_overrides
AttributeLoader
became obsolete and was removedApplication::loadSettings
ElggEntity::addToSite
ElggEntity::disableMetadata
ElggEntity::enableMetadata
ElggEntity::getSites
ElggEntity::removeFromSite
ElggEntity::isFullyLoaded
ElggEntity::clearAllFiles
ElggPlugin::getFriendlyName
: UseElggPlugin::getDisplayName()
ElggPlugin::setID
ElggPlugin::unsetAllUsersSettings
ElggFile::setFilestore
: ElggFile objects can no longer use custom filestores.ElggFile::size
: UsegetSize
ElggDiskFilestore::makeFileMatrix
: UseElgg\EntityDirLocator
ElggData::get
: Usually can be replaced by property readElggData::getClassName
: Useget_class()
ElggData::set
: Usually can be replaced by property writeElggEntity::setURL
: SeegetURL
for details on the plugin hookElggMenuBuilder::compareByWeight
: UsecompareByPriority
ElggMenuItem::getWeight
: UsegetPriority
ElggMenuItem::getContent
: Useelgg_view_menu_item()
ElggMenuItem::setWeight
: UsesetPriority
ElggRiverItem::getPostedTime
: UsegetTimePosted
ElggSession
has removed all deprecated methodsElggSite::addEntity
ElggSite::addObject
ElggSite::addUser
ElggSite::getEntities
: Useelgg_get_entities()
ElggSite::getExportableValues
: UsetoObject
ElggSite::getMembers
: Useelgg_get_entities()
ElggSite::getObjects
: Useelgg_get_entities()
ElggSite::listMembers
: Useelgg_list_entities()
ElggSite::removeEntity
ElggSite::removeObject
ElggSite::removeUser
ElggSite::isPublicPage
: Logic moved to the router and should not be accessed directlyElggSite::checkWalledGarden
: Logic moved to the router and should not be accessed directlyElggUser::countObjects
: Useelgg_get_entities()
Logger::getClassName
: Useget_class()
Elgg\Application\Database::getTablePrefix
: Read theprefix
propertyelgg_view_access_collections()
ElggSession::get_ignore_access
: UsegetIgnoreAccess
ElggSession::set_ignore_access
: UsesetIgnoreAccess
profile_pagesetup
pages_can_delete_page
: Use$entity->canDelete()
pages_search_pages
pages_is_page
: use$entity instanceof ElggPage
discussion_comment_override
: See :ref:`upgrade-discussion-replies`discussion_can_edit_reply
: See :ref:`upgrade-discussion-replies`discussion_reply_menu_setup
: See :ref:`upgrade-discussion-replies`discussion_reply_container_logic_override
: See :ref:`upgrade-discussion-replies`discussion_reply_container_permissions_override
: See :ref:`upgrade-discussion-replies`discussion_update_reply_access_ids
: See :ref:`upgrade-discussion-replies`discussion_search_discussion
: See :ref:`upgrade-discussion-replies`discussion_add_to_river_menu
: See :ref:`upgrade-discussion-replies`discussion_prepare_reply_notification
: See :ref:`upgrade-discussion-replies`discussion_redirect_to_reply
: See :ref:`upgrade-discussion-replies`discussion_ecml_views_hook
: See :ref:`upgrade-discussion-replies`search_get_where_sql
search_get_ft_min_max
search_get_order_by_sql
search_consolidate_substrings
search_remove_ignored_words
search_get_highlighted_relevant_substrings
search_highlight_words
search_get_search_view
search_custom_types_tags_hook
search_tags_hook
search_users_hook
search_groups_hook
search_objects_hook
members_list_popular
members_list_newest
members_list_online
members_list_alpha
members_nav_popular
members_nav_newest
members_nav_online
members_nav_alpha
uservalidationbyemail_generate_code
- All functions around entity subtypes table:
add_subtype
: Useelgg_set_entity_class
at runtimeupdate_subtype
: Useelgg_set_entity_class
at runtimeremove_subtype
get_subtype_id
get_subtype_from_id
get_subtype_class
: Useelgg_get_entity_class
get_subtype_class_from_id
- All caches have been consolidated into a single API layer. The following functions and methods have been removed:
is_memcache_available
_elgg_get_memcache
_elgg_invalidate_memcache_for_entity
ElggMemcache
ElggFileCache
ElggStaticVariableCache
ElggSharedMemoryCache
Elgg\Cache\Pool
interface and all extending classes
- As a result of system log changes:
system_log_default_logger
: moved tosystem_log
pluginsystem_log_listener
: moved tosystem_log
pluginsystem_log
: moved tosystem_log
pluginget_system_log
: renamed tosystem_log_get_log
and moved tosystem_log
pluginget_log_entry
: renamed tosystem_log_get_log_entry
and moved tosystem_log
pluginget_object_from_log_entry
: renamed tosystem_log_get_object_from_log_entry
and moved tosystem_log
pluginarchive_log
: renamed tosystem_log_archive_log
and moved tosystem_log
pluginlogbrowser_user_hover_menu
: renamed tosystem_log_user_hover_menu
and moved tosystem_log
pluginlogrotate_archive_cron
: renamed tosystem_log_archive_cron
and moved tosystem_log
pluginlogrotate_delete_cron
: renamed tosystem_log_delete_cron
and moved tosystem_log
pluginlogrotate_get_seconds_in_period
: renamed tosystem_log_get_seconds_in_period
and moved tosystem_log
pluginlog_browser_delete_log
: renamed tosystem_log_browser_delete_log
and moved tosystem_log
plugin
ban_user
: UseElggUser->ban()
create_metadata
: UseElggEntity
setter orElggEntity->setMetadata()
update_metadata
: UseElggMetadata->save()
get_metadata_url
create_annotation
: UseElggEntity->annotate()
update_metadata
: UseElggAnnotation->save()
elgg_get_user_validation_status
: UseElggUser->isValidated()
make_user_admin
: UseElggUser->makeAdmin()
remove_user_admin
: UseElggUser->removeAdmin()
unban_user
: UseElggUser->unban()
elgg_get_entities_from_attributes
: Useelgg_get_entities()
elgg_get_entities_from_metadata
: Useelgg_get_entities()
elgg_get_entities_from_relationship
: Useelgg_get_entities()
elgg_get_entities_from_private_settings
: Useelgg_get_entities()
elgg_get_entities_from_access_id
: Useelgg_get_entities()
elgg_list_entities_from_metadata
: Useelgg_list_entities()
elgg_list_entities_from_relationship
: Useelgg_list_entities()
elgg_list_entities_from_private_settings
: Useelgg_list_entities()
elgg_list_entities_from_access_id
: Useelgg_list_entities()
elgg_list_registered_entities
: Useelgg_list_entities()
elgg_batch_delete_callback
\Elgg\Project\Paths::sanitize
: Use\Elgg\Project\Paths::sanitize()
elgg_group_gatekeeper
: Useelgg_entity_gatekeeper()
get_entity_dates
: Useelgg_get_entity_dates()
messages_set_url
: UseElggEntity::getURL()
$CURRENT_SYSTEM_VIEWTYPE
$DEFAULT_FILE_STORE
$ENTITY_CACHE
$SESSION
: Use the API provided byelgg_get_session()
$CONFIG->site_id
: Use1
$CONFIG->search_info
$CONFIG->input
: Useset_input
andget_input
FilePluginFile
: replace withElggFile
(or load withget_entity()
)Elgg_Notifications_Notification
Elgg\Database\EntityTable\UserFetchResultException.php
Elgg\Database\MetastringsTable
Elgg\Database\SubtypeTable
Exportable
and its methodsexport
andgetExportableValues
: UsetoObject
ExportException
Importable
and its methodimport
.ImportException
ODD
and all classes beginning withODD*
.XmlElement
Elgg_Notifications_Event
: Use\Elgg\Notifications\Event
Elgg\Mail\Address
: useElgg\Email\Address
ElggDiscussionReply
: userElggComment
see :ref:`upgrade-discussion-replies`
The storage engine for the database tables has been changed from MyISAM to InnoDB. You maybe need to optimize your database settings for this change.
The datalists
table has been removed. All settings from datalists table have been merged into the config
table.
Metastrings in the database have been denormalized for performance purposes. We removed the metastrings table and put all the string values directly in the
metadata and annotation tables. You need to update your custom queries to reflect these changes. Also the msv
and msn
table aliases are no longer available.
It is best practice not to rely on the table aliases used in core queries. If you need to use custom clauses you should do your own joins.
From the "users_entity" table, the password
and hash
columns have been removed.
The geocode_cache
table has been removed as it was no longer used.
subtype
column in entities
table no longer holds a subtype ID, but a subtype string
entity_subtypes
table has been dropped.
type
, subtype
and access_id
columns in river
table have been dropped.
For queries without elgg_get_river()
join the entities
table on object_guid
to check the type and the subtype of the entity.
Access column hasn't been in use for some time: queries are built to ensure access to all three entities (subject, object and target).
elgg_get_entities
now accepts all options that were previously distributed between elgg_get_entities_from_metadata
,
elgg_get_entities_from_annotations
, elgg_get_entities_from_relationship
, elgg_get_entities_from_private_settings
and elgg_get_entities_from_access_id
. The latter have been been deprecated.
Passing raw MySQL statements to options is deprecated. Plugins are advised to use closures that receive an instance of
\Elgg\Database\QueryBuilder
and prepare the statement using database abstraction layer. On one hand this will ensure
that all statements are properly sanitized using the database driver, on the other hand it will allow us to transition
to testable object-oriented query building.
wheres
statements should not use raw SQL strings, instead pass an instance of \Elgg\Database\Clauses\WhereClause
or a closure that returns an instance of \Doctrine\DBAL\Query\Expression\CompositeExpression
:
elgg_get_entities([
'wheres' => [
function(\Elgg\Database\QueryBuilder $qb, $alias) {
$joined_alias = $qb->joinMetadataTable($alias, 'guid', 'status');
return $qb->compare("$joined_alias.name", 'in', ['draft', 'unsaved_draft'], ELGG_VALUE_STRING);
}
]
]);
joins
, order_by
, group_by
, selects
clauses should not use raw SQL strings. Use closures that receive
an instance of \Elgg\Database\QueryBuilder
and return a prepared statement.
The reverse_order_by
option has been removed.
Plugins should not rely on joined and selected table aliases. Closures passed to the options array will receive a second argument that corresponds to the selected table alias. Plugins must perform their own joins and use joined aliases accordingly.
Note that all of the private API around building raw SQL strings has also been removed. If you were relying on them in your plugins,
be advised that anything marked as @access private
or @internal
in core can be modified and removed at any time, and we do not guarantee
any backward compatibility for those functions. DO NOT USE THEM. If you find yourself needing to use them, open an issue
on Github and we will consider adding a public equivalent.
Storage of metadata, annotation and private setting values has been aligned.
Boolean values are cast to integers when saved: false
is stored as 0
and true
is stored as 1
.
This has breaking implications for private settings, which were previously stored as empty strings for false
values.
Plugins should write their own migration scripts to alter DB values from empty strings to 0
(for private settings that
are expected to store boolean values) to ensure that elgg_get_entities()
can retrieve these values
with private_setting_name_value_pairs
containing false
values. This applies to plugin settings, as well as
any private settings added to entities.
Metadata is no longer access controlled. If your plugin created metadata with restricted access, those restrictions will not be honored. You should use annotations or entities instead, which do provide access control.
Do not read or write to the access_id
property on ElggMetadata objects.
Metadata is no longer enabled or disabled. You can no longer perform the enable
and disable
API calls on metadata.
Metadata no longer has an owner_guid
. It is no longer possible to query metadata based on owner_guids
.
Subsequently, ElggMetadata::canEdit()
will always return true
regardless of the logged in user, unless explicitly overriden by a plugin hook.
User capabilities service will no longer trigger permission check hooks when:
- permissions are checked for an admin user
- permissions are checked when access is ignored with
elgg_set_ignore_access()
This means that plugins can no longer alter permissions in aforementioned cases.
elgg_check_access_overrides()
has been removed, as plugins will no longer need to validate access overrides.
The translations for the default Elgg access levels have new translation language keys.
Pre 3.0 Elgg has some (partial) support for having multiple sites in the same database. This Multi Site concept has been completely removed in 3.0. Entities no longer have the site_guid attribute. This means there is no longer the ability to have entities on different sites. If you currently have multiple sites in your database, upgrading Elgg to 3.0 will fail. You need to separate the different sites into separate databases/tables.
Related to the removal of the Multi Site concept in Elgg, there is no longer a need for entities having a 'member_of_site' relationship with the Site Entity. All functions related to adding/removing this relationship has been removed. All existing relationships will be removed as part of this upgrade.
Setting ElggSite::$url
has no effect. Reading the site URL always pulls from the $CONFIG->wwwroot
set in
settings.php, or computed by Symphony Request.
ElggSite::save()
will fail if it isn't the main site.
The subtable sites_entity
for ElggSite
no longer exists. All attributes have been moved to metadata.
The subtable groups_entity
for ElggGroup
no longer exists. All attributes have been moved to metadata.
The subtable objects_entity
for ElggObject
no longer exists. All attributes have been moved to metadata.
The subtable users_entity
for ElggUser
no longer exists. All attributes have been moved to metadata.
If you have custom queries referencing this table you need to update them.
If you have function that rely on Entity->getOriginalAttributes()
be advised that this will only return the base attributes of an ElggEntity
and
no longer contain the secondary attributes.
The access collections table now has a subtype column. This extra data helps identifying the purpose of the ACL. The user owned access collections are assumed to be used as Friends Collections and now have the 'friends_collection' subtype. The groups access collection information was previously stored in the group_acl metadata. With the introduction of the ACL subtype this information has been moved to the ACL subtype attribute.
The ACCESS_FRIENDS
access_id has been migrated to an actual access collection (with the subtype friends
). All entities and annotations have been updated to use the new
access collection id. The access collection is created when a user is created. When a relationship of the type friends
is created, the related guid will
also be added to the access collection. You can no longer save or update entities with the access id ACCESS_FRIENDS
.
Entity subtypes have been denormalized.
entity_subtypes
table has been removed and subtype
column in entities table simply holds the string representation of the subtype.
Consequently, all API around adding/updating entity subtypes and classes have been removed.
Plugins can now use elgg_set_entity_class()
and elgg_get_entity_class()
to register a custom entity class at runtime (e.g. in system init handler).
All entities now MUST have a subtype. By default, the following subtypes are added and reserved:
user
for usersgroup
for groupssite
for sites
Elgg no longer provides API functions to register custom classes. If you need custom classes you can
use PSR-0
classes in the /classes
folder of your plugin or use composer for autoloading of additional classes.
The following class registration related functions have been removed:
elgg_get_class_loader
elgg_register_class
elgg_register_classes
Plugins can now define their services and attach them to Elgg's public DI container by providing definitions in
elgg-services.php
in the root of the plugin directory.
elgg()
no longer returns an instance of Elgg application, but a DI container instance.
We have added a search service into core, consequently the search
plugin now only provides a user interface for displaying forms and listing search results.
Many of the views in the search plugin have been affected by this change.
The FULLTEXT indices have been removed on various tables. The search plugin will now always use a like query when performing a search.
See :doc:`Search Service </guides/search>` and :ref:`Search hooks <guides/hooks-list#search>` documentation for detailed information about new search capabilities.
input/password
: by default this field will no longer show a value passed to it, this can be overridden by passing the view varalways_empty
and set it to falseinput/submit
,input/reset
andinput/button
are now rendered with a<button>
instead of the<input>
tag. These input view also accepttext
andicon
parameters.output/url
now sets.elgg-anchor
class on anchor elements and acceptsicon
parameter. If notext
is set, thehref
parameter used as a label will be restricted to 100 characters.output/url
now supports abadge
parameter, which can be used where a counter, a badge, or similar is required as a postfix (mainly in menu items that have counters).output/tags
no longer uses<ul>
tags with floats and instead it relies on inherently inline elements such as<span>
and<a>
The Entity and River menu now shows all the items in a dropdown. Social actions like liking or commenting are moved to an alternate menu called the social menu, which is meant for social actions.
elgg_register_library
and elgg_load_library
have been removed.
These functions had little impact on performance (especially with OPCache enabled), and made it difficult for other plugins to work with APIs contained in libraries.
Additionally it was difficult for developers to know that APIs were contained in a library while there being autocompleted by IDE.
If you are concerned with performance, move the logic to classes and let PHP autoload them as necessary, otherwise use require_once
and require your libraries.
file/download
file/search
groupicon
twitterservice
collections/pickercallback
discussion/reply
: See :ref:`upgrade-discussion-replies`expages
invitefriends
: Usefriends/{username}/invite
messages/compose
: Usemessages/add
reportedcontent
file/download
: Useelgg_get_inline_url
orelgg_get_download_url
file/delete
: Useentity/delete
actionimport/opendd
discussion/reply/save
: See :ref:`upgrade-discussion-replies`discussion/reply/delete
: See :ref:`upgrade-discussion-replies`comment/delete
: Useentity/delete
actionuservalidationbyemail/bulk_action
: useadmin/user/bulk/validate
oradmin/user/bulk/delete
uservalidationbyemail/delete
: useadmin/user/bulk/delete
uservalidationbyemail/validate
: useadmin/user/bulk/validate
invitefriends/invite
: usefriends/invite
ElggData
(and hence most Elgg domain objects) no longer implementsExportable
ElggEntity
no longer implementsImportable
ElggGroup
no longer implementsFriendable
ElggRelationship
no longer implementsImportable
ElggSession
no longer implementsArrayAccess
Elgg\Application\Database
no longer extendsElgg\Database
admin.js
elgg.widgets
: Use theelgg/widgets
module. The "widgets" layouts do this module automaticallylightbox.js
: Use theelgg/lightbox
module as neededlightbox/settings.js
: Use thegetOptions, ui.lightbox
JS hook or thedata-colorbox-opts
attributeelgg.ui.popupClose
: Use theelgg/popup
moduleelgg.ui.popupOpen
: Use theelgg/popup
moduleelgg.ui.initAccessInputs
elgg.ui.river
elgg.ui.initDatePicker
: Use theinput/date
moduleelgg.ui.likesPopupHandler
elgg.embed
: Use theelgg/embed
moduleelgg.discussion
: Use theelgg/discussion
moduleembed/custom_insert_js
: Use theembed, editor
JS hookelgg/ckeditor.js
: replaced byelgg-ckeditor.js
elgg/ckeditor/set-basepath.js
elgg/ckeditor/insert.js
jQuery.cookie
: Useelgg.session.cookie
jquery.jeditable
likes.js
: Theelgg/likes
module is loaded automaticallymessageboard.js
elgg.autocomplete
is no longer defined.elgg.messageboard
is no longer defined.jQuery.fn.friendsPicker
elgg.ui.toggleMenu
is no longer definedelgg.ui.toggleMenuItems
: Usedata-toggle
attribute when registering toggleable menu itemsuservalidationbyemail/js.php
: Use theelgg/uservalidationbyemail
modulediscussion.js
: See :ref:`upgrade-discussion-replies`
- Event login, user: Use login:before or login:after. Note the user is not logged in during the login:before event
- Event delete, annotations: Use delete, annotation
- Event pagesetup, system: Use the menu or page shell hooks instead
- Event upgrade, upgrade: Use upgrade, system instead
- Hook index, system: Override the
resources/index
view- Hook object:notifications, <type>: Use the hook send:before, notifications
- Hook output:before, layout: Use view_vars, page/layout/<layout_name>
- Hook output:after, layout: Use view, page/layout/<layout_name>
- Hook email, system: Use more granular <hook>, system:email hooks
- Hook email:message, system: Use zend:message, system:email hook
- Hook members:list, <page>: Use your own pagehandler or route hook
- Hook members:config, <page>: Use register, menu:filter:members
- Hook profile_buttons, group: Use register, menu:title
notificationsettings/save
form and actionnotificationsettings/groupsave
form and actiondiscussion/reply/save
form and action
ElggEntity::getAnnotations
ElggEntity::getEntitiesFromRelationship
ElggGroup::getMembers
ElggUser::getGroups
ElggUser::getFriends
(as part ofFriendable
)ElggUser::getFriendsOf
(as part ofFriendable
)ElggUser::getFriendsObjects
(as part ofFriendable
)ElggUser::getObjects
(as part ofFriendable
)find_active_users
elgg_get_admin_notices
elgg_get_all_plugin_user_settings
elgg_set_plugin_user_setting
elgg_unset_plugin_user_setting
elgg_get_plugin_user_setting
elgg_set_plugin_setting
elgg_get_plugin_setting
elgg_unset_plugin_setting
elgg_unset_all_plugin_settings
ElggAnnotation
: No longer accepts an annotation IDElggGroup
: No longer accepts a GUIDElggMetadata
: No longer accepts a metadata IDElggObject
: No longer accepts a GUIDElggRelationship
: No longer accepts a relationship ID ornull
ElggSite
: No longer accepts a GUID or URLElggUser
: No longer accepts a GUID or usernameElggPlugin
: No longer accepts a GUID or path. UseElggPlugin::fromId
to construct a plugin from its path
ElggBatch
: You may only access public propertiesElggEntity
: Thetables_split
andtables_loaded
properties were removedElggEntity
: Empty URLs will no longer be normalized. This means entities without URLs will no longer result in the site URLElggGroup::removeObjectFromGroup
requires passing in anElggObject
(no longer accepts a GUID)ElggUser::$salt
no longer exists as an attribute, nor is it used for authenticationElggUser::$password
no longer exists as an attribute, nor is it used for authenticationelgg_get_widget_types
no longer supports$exact
as the 2nd argumentelgg_instanceof
no longer supports the fourthclass
argumentelgg_view
: The 3rd and 4th (unused) arguments have been removed. If you use the$viewtype
argument, you must update your usage.elgg_view_icon
no longer supportstrue
as the 2nd argumentelgg_list_entities
no longer supports the optionview_type_toggle
elgg_list_registered_entities
no longer supports the optionview_type_toggle
elgg_log
no longer accepts the level"DEBUG"
elgg_dump
no longer accepts a$to_screen
argument.elgg_gatekeeper
andelgg_admin_gatekeeper
no longer reportlogin
oradmin
as forward reason, but403
Application::getDb()
no longer returns an instance ofElgg\Database
, but rather aElgg\Application\Database
$CONFIG
is no longer available as a local variable inside pluginstart.php
files.elgg_get_config('siteemail')
is no longer available. Useelgg_get_site_entity()->email
.ElggEntity::saveIconFromUploadedFile
only saves master size, the other sizes are created when requested byElggEntity::getIcon()
based on the master sizeElggEntity::saveIconFromLocalFile
only saves master size, the other sizes are created when requested byElggEntity::getIcon()
based on the master sizeElggEntity::saveIconFromElggFile
only saves master size, the other sizes are created when requested byElggEntity::getIcon()
based on the master size- Group entities do no longer have the magic
username
attribute.- Pagehandling will no longer detect
group:<guid>
in the URL- The CRON interval
reboot
is removed.- The URL endpoints
js/
andcss/
are no longer supported. Useelgg_get_simplecache_url()
.- The generic comment save action no longer sends the notification directly, this has been offloaded to the notification system.
- The script
engine/start.php
is removed.- The functions
set_config
,unset_config
andget_config
have been deprecated and replaced byelgg_set_config
,elgg_remove_config
andelgg_get_config
.- Config values
path
,wwwroot
, anddataroot
are not read from the database. The settings.php file values are always used.- Config functions like
elgg_get_config
no longer trim keys.- If you override the view
navigation/menu/user_hover/placeholder
, you must change the config keylazy_hover:menus
toelgg_lazy_hover_menus
.- The config value
entity_types
is no longer present or used.- Uploaded images are autorotated based on their orientation metadata.
- The view
object/widget/edit/num_display
now uses aninput/number
field instead ofinput/select
; you might need to update your widget edit views accordingly.- Annotation names are no longer trimmed during save
An extended view now will receive all the regular hooks (like the view_vars hook). It now is also possible to extend view extensions. With this change in behaviour all view rendering will behave the same. It no longer matters if it was used as an extension or not.
When registering for 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.
The widget layout usage has been changed. Content is no longer drawn as part of the layout. You need to wrap you content
in another layout and use the widgets layout as part of your content. If you want some special content to show if there
are no widgets in the layout, you can now pass a special no_widgets
parameter (as String or as a Closure).
When registering widgets you can no longer omit passing a context as the all
context is no longer supported. You need
to explicitely pass the contexts for which the widget is intended.
Page handling using elgg_register_page_handler()
has been deprecated.
We have added new routing API using elgg_register_route()
, which allows plugins to define
named routes, subsequently using route names to generate URLs using elgg_generate_url()
.
See :doc:`routing </guides/routing>` docs for details.
As a result of this change all core page handlers have been removed, and any logic contained within these page handlers has been moved to respective resource views.
elgg_generate_entity_url()
has been added as shortcut way to generate URLs from named
routes that depend on entity type and subtype.
Use of handler
parameter in entity menus has been deprecated in favour of named entity routes.
Gatekeeper function have been refactored to serve as middleware in the routing process, and as such they no longer return values. These functions throw HTTP exceptions that are then routed to error pages and can be redirected to other pages via hooks.
Entity and collection labelling conventions have changed to comply with the new routing patterns:
return [
'item:object:blog' => 'Blog',
'collection:object:blog' => 'Blogs',
'collection:object:blog:all' => 'All site blogs',
'collection:object:blog:owner' => '%s\'s blogs',
'collection:object:blog:group' => 'Group blogs',
'collection:object:blog:friends' => 'Friends\' blogs',
'add:object:blog' => 'Add blog post',
'edit:object:blog' => 'Edit blog post',
];
These conventions are used across the routing and navigation systems, so plugins are advised to follow them.
set_input()
and get_input()
no longer trim values.
All core and core plugin actions now all use the new Http Response functions like elgg_ok_response and elgg_error_response instead of forward(). The effect of this change is that is most cases the 'forward', 'system' hook is no longer triggered. If you like to influence the responses you now can use the 'response', 'action:<name/of/action>' hook. This gives you more control over the response and allows to target a specific action very easily.
- Do not call
elgg_load_library('htmlawed')
.- In the hook params for
'config', 'htmlawed'
, thehook_tag
function name changed.
one_column
, one_sidebar
, two_sidebar
and content
layouts have been removed - instead layout rendering has been centralized in the default
. Updated default
layout provides full control over the layout elements via $vars
.
For maximum backwards compatibility, calls to elgg_view_layout()
with these layout names will still yield expected output, but the plugins should start using the default
layout with an updated set of parameters.
Page layouts have been decomposed into smaller elements, which should make it easier for themes to target specific layout elements without having to override layouts at large.
As a result of these changes:
- all layouts are consistent in how they handle title and filter menus, breadcrumbs and layout subviews
- all layouts can now be easily extended to have multiple tabs. Plugins can pass
filter_id
parameter that will allow other plugins to hook intoregister, menu:filter:<filter_id>
hook and add new tabs. If nofilter_id
is provided, defaultregister, menu:filter
hook can be used.- layout views and subviews now receive
identifier
andsegments
of the page being rendered- layout parameters are available to title and filter menu hooks, which allows resources to provide additional context information, for example, an
$entity
in case of a profile resource
Plugins and themes should:
- Update calls to
elgg_view_layout()
to usedefault
layout- Update replace
nav
parameter in layout views withbreadcrumbs
parameter- Update their use of
filter
parameter in layout views by either providing a default set of filter tabs, or setting afilter_id
parameter and using hooks- Remove
page/layouts/one_column
view- Remove
page/layouts/one_sidebar
view- Remove
page/layouts/two_sidebar
view- Remove
page/layouts/content
view- Update their use of
page/layouts/default
- Update their use of
page/layouts/error
- Update their use of
page/layouts/elements/filter
- Update their use of
page/layouts/elements/header
- Update their use of
page/layouts/elements/footer
- Update their use of
page/elements/title
- Update their use of
navigation/breadcrumbs
to pass$vars['breadcrumbs']
toelgg_get_breadcrumbs()
- Update hook registrations for
output:before, layout
toview_vars, page/layout/<layout_name>
- Update hook registrations for
output:after, layout
toview, page/layout/<layout_name>
Likes no longer uses Elgg's toggle API, so only a single likes
menu item is used. The add/remove actions no longer return Ajax values directly, as likes status data is now returned with every Ajax request that sends a "guid". When the number of likes is zero, the likes_count
menu item is now hidden by adding .hidden to the LI element, instead of the anchor. Also the likes_count
menu item is a regular link, and is no longer created by the likes/count
view.
Notifications plugin has been rewritten dropping many views and actions. The purpose of this rewrite was to implement a more efficient, extendable and scalable interface for managing notifications preferences. We have implemented a much simpler markup and removed excessive styling and javascript that was required to make the old interface work.
If your plugin is extending any of the views or relies on any actions in the notifications plugin, it has to be updated.
The suptype page_top
has been migrated into the subtype page
. The subtype page
has it's own class namely ElggPage
. In order to check
if an ElggPage
is a top page the class function ElggPage->isTopPage()
was added.
All pages have a metadata value for parent_guid
, for top pages this contains 0
.
All profile related functionality has been moved out of core into this plugin. Most noteable are the profile field admin utility and the hook to set up the profile fields config data.
The Data Views plugin no longer comes bundled.
The twitter_api
plugin has been removed from the Elgg core. The plugin is still available as the Composer package
elgg/twitter_api, in order to install it add the following to you
composer.json
require
section:
{
"require": {
"elgg/twitter_api": "~1.9"
}
}
The legacy_urls
plugin has been removed from the Elgg core. The plugin is still available as the Composer package
elgg/legacy_urls, in order to install it add the following to you
composer.json
require
section:
{
"require": {
"elgg/legacy_urls": "~2.3"
}
}
The listing view of unvalidated users has been moved from the plugin to Elgg core. Some generic action (eg. validate and delete) have also been moved to Elgg core.
To provide for more granularity in email handling and delivery, email, system hook has been removed. New email service provides for several other replacement hooks that allow plugins to control email content, format, and transport used for delivery.
elgg_set_email_transport()
can now be used to replace the default Sendmail transport with another instance of
\Zend\Mail\Transport\TransportInterface
, e.g. SMTP, in-memory, or file transport. Note that this function
must be called early in the boot process. Note that if you call this function on each request, using
plugin settings to determine transport config may not be very efficient - store these settings in
as datalist or site config values, so they are loaded from boot cache.
Aalborg theme is no longer bundled with Elgg. Default core theme is now based on Aalboard, but it has undergone major changes.
Notable changes in plugins:
- Topbar, navbar and header have been combined into a single responsive topbar component
- Default inner width is now 1280px (80rem * 16px/1rem)
- Preferred unit of measurement is now rem and not px
- The theme uses 8-point grid system <https://builttoadapt.io/intro-to-the-8-point-grid-system-d2573cde8632>
- Menus, layout elements and other components now use flexbox
- Reset is done using 8-point grid system <https://necolas.github.io/normalize.css/>
- Media queries have been rewritten for mobile-first experience
- Form elements (text inputs, buttons and selects) now have an equal height of 2.5rem
- Layout header is now positioned outside of the layout columns, which have been wrapped into
elgg-layout-columns
- z-index properties have been reviewed and stacked with simple iteration instead of 9999999 <https://hackernoon.com/my-approach-to-using-z-index-eca67feb079c>.
- Color scheme has been changed to highlight actionable elements and reduce abundance of gray shades
- search plugin no longer extends
page/elements/header
and insteadpage/elements/topbar
renderssearch/search_box
view.elgg-icon
no longer has a globalfont-size
,line-height
orcolor
: these values will be inherited from parent items- Support for
.elgg-icon-hover
has been dropped- User "hover" icons are no longer covered with a "caret" icon
Read more about :doc:`Theming Principles </guides/themes>`
Also note, CSS views served via /cache
URLs are pre-processed using CSS Crush <http://the-echoplex.net/csscrush/>. If you make references to CSS variables or other elements, the definition must be located within the same view output. E.g. A variable defined in elgg.css
cannot be referenced in a separate CSS file like colorbox.css
.
Submitting comments is now AJAXed. After a succesful submission the comment list will be updated automatically.
The following changes have been made to the comment notifications.
- The language keys related to comment notifications have changed. Check the
generic_comment:notification:owner:
language keys- The action for creating a comment (
action/comment/save
) was changed. If your plugin overruled this action you should have a look at it in order to prevent double notifications
object/elements/full/body
now wraps the full listing body in a.elgg-listing-full-body
wrapperobject/elements/full
now supportsattachments
andresponses
which are rendered after listing body- In core plugins, resource views no longer render comments/replies - instead they pass a
show_responses
flag to the entity view, which renders the responses and passes them to the full listing view. Third party plugins will need to update their uses ofobject/<subtype>
andresources/<handler>/view
views.- Full discussion view is now rendered using
object/elements/full
viewobject/file
now passes image (specialcontent) view as anattachment
to the full listing view
Default sorting of menu items has been changed from text
to priority
.
Note that register
and prepare
hooks now use collections API. For the most part, all hooks should continue working, as long as they are not performing complex operations with arrays.
Support for icon
and badge
parameters was added. Plugins should start using these parameters and prefer them to a single text
parameter. CSS should be used to control visibility of the label, icon and badge, instead of conditionals in preparing menu items.
All menus are now wrapped with nav.elgg-menu-container
to ensure that multiple menu sections have a single parent element, and can be styled using flexbox or floats.
All menu items are now identified with with data-menu-item
attribute, sections - with data-menu-section
, containers with - data-menu-name
attributes.
topbar
menu:
account
menu item with priority800
added toalt
sectionsite_notifications
menu item is now a child ofaccount
with priority100
usersettings
menu item is now a child ofaccount
with priority300
administration
menu item is now a child ofaccount
with priority800
logout
menu item is now a child ofaccount
with priority900
dashboard
menu item now is now a child ofacount
has priority of100
- In
default
section (profile
,friends
,messages
), core menu items now useicon
parameter and use CSS to hide the label. Plugins that register items to this section and expect a visible label need to update their CSS.profile
menu item is now a child ofaccount
friends
menu item is now a child ofaccount
entity
menu:
access
menu item has been removed. Access information is now rendered in the entity byline.
user_hover
menu:
- All items use the
icon
parameter.- The layout of the dropdown has been changed. If you have modified the look and feel of this dropdown, you might need to update your HTML/CSS.
widget
menu:
collapse
menu item has been removed and CSS updated accordingly
title
menu:
The profile
plugin no longer uses the actions section of the user_hover
menu, but registers regulare title
menu items.
extras
menu:
This menu has been removed from the page layout. Menu items that registered for this menu have been moved to other menus.
groups:my_status
menu:
This menu has been removed from the group profile page.
site_notifications
menu:
This menu has been removed. Site Notification objects now use the entity menu for actions.
site
menu:
Registration of custom menu item defined in admin interface has been moved to register, menu:site
hook.
navigation/menu/site
view has been removed. Site menu now adds a more` menu item directly to the ``default
section.
Default icon image files have been moved and re-mapped as follows:
- Default icons:
views/default/icon/default/$size.png
- User icons:
views/default/icon/user/default/$size.gif
- Group icons:
views/default/icon/group/default/$size.gif
in the groups plugin
Groups icon files have been moved from groups/<guid><size>.jpg
relative to group owner's directory on filestore to a location prescribed by the entity icon service. Plugins should stop accessing files on the filestore directly and use the entity icon API. Upgrade script is available via admin interface.
The generation of entity icons has ben changed. No longer will all the configured sizes be generated when calling one of the entity icon functions
(ElggEntity::saveIconFromUploadedFile
, ElggEntity::saveIconFromLocalFile
or ElggEntity::saveIconFromElggFile
), but only the master size.
The other configured sizes will be generated when requesting that size based of the master icon.
FontAwesome has been upgraded to version 5.0+. There were certain changes to how FontAwesome glyphs are rendered. The core will take care of most changes (e.g. mapping old icon names to new ones, and using the correct prefix for brand and solid icons).
Friends Picker input is now rendered using input/userpicker
.
Plugins should:
- Update overriden
input/userpicker
to support newonly_friends
parameter- Remove friends picker CSS from their stylesheets
Friends collections UI has been moved to its own plugins - friends_collections
.
In 3.0, these elements by default no longer stretch to fill available space in a block context. They still clear floats and allow breaking words to wrap text.
Core modules and layouts that relied on space-filling have been reworked for Flexbox and
we encourage devs to do the same, rather than use the problematic overflow: hidden
.
The function elgg_delete_river()
which was deprecated in 2.3, has been reinstated. Notable changes between the internals of this function are;
- It accepts all
$options
fromelgg_get_river()
but requires at least one of the following params to be set id(s), annotation_id(s), subject_guid(s), object_guid(s), target_guid(s) or view(s)- Since
elgg_get_river
by default has a limit on the number of river items it fetches, if you wish to remove all river items you need to setlimit
tofalse
- Access is ignored when deleting river items
- Events are fired just before and after a river item has been deleted
Since discussion replies where mostly a carbon copy of comments, all discussion replies have been migrated to comments. All related action, hooks, event, language keys etc. have been removed.
Note
Discussion comments will now show up in the Comments section of Search, no longer under the Discussion section.
All plugins have been scanned for unused translation keys. The unused keys have been removed. If there was a generic translation available for the custom translation key, these have also been updated.
System log API has been moved out of core into a system_log
plugin.
logbrowser
and logrotate
plugins have been merged into the system_log
plugin.
Sending elgg_log()
and PHP error messages to page output is now only possible via the developers plugin "Log to the screen" setting. See the settings.example.php
file for more information on using $CONFIG->debug
in your settings.php
file. Debugging should generally be done via the xdebug
extension or tail -f /path/to/error.log
on your server.
Assets are now loaded from https://asset-packagist.org. FXP composer asset plugin is no longer required when installing Elgg or updating composer dependencies.
The cron logs are no longer stored in the database, but on the filesystem (in dataroot). This will allow longer output to be stored. A migration script was added to migrate the old database settings to the new location and remove the old values from the database.
- The language keys related to comment notifications have changed. Check the
generic_comment:notification:owner:
language keys
New 3.0 installations require MySQL 5.5.3 (or higher) and use the utf8mb4 character set and LONGTEXT content columns (notably allowing storing longer content and extended characters like emoji).
The settings "Allow visitors to register" and "Restrict pages to logged-in users" now appear on the Basic Settings admin page.
The twitter_api
plugin no longer comes bundled with Elgg.
Elgg's PHPUnit bootstrap can now handle both unit and integration tests. Please note that you shouldn't run tests on a production site, as it may damage data integrity. To prevent data loss, you need to specify database settings via environment variables. You can do so via the phpunit.xml bootstrap.
Plugins can now implement their own PHPUnit tests by extending \Elgg\UnitTestCase
and \Elgg\IntegrationTestCase
classes.
plugins
test suite will automatically autoload PHPUnit tests from mod/<plugin_id>/tests/phpunit/unit
and
mod/<plugin_id>/tests/phpunit/integration
.
Prior to running integration tests, you need to enable the plugins that you wish to test alongside core API.
\Elgg\IntegrationTestCase
uses \Elgg\Seeding
trait, which can be used to conveniently build new entities and
write them to the database.
\Elgg\UnitTestCase
does not use the database, but provides a database mocking interface, which allows tests to
define query specs with predefined returns.
By default, both unit and integration tests will be run whenever phpunit
is called. You can use --testsuite
flag to only run a specific suite: phpunit --testsuite unit
or phpunit --testsuite integration
or phpunit --testsuite plugins
.
For integration testing to run properly, plugins are advised to not put any logic into the root of start.php
, and instead
return a Closure. This allows the testsuite to build a new Application instance without loosing plugin initialization logic.
Plugins with simpletests will continue working as perviously. However, method signatures in the ElggCoreUnitTest
abstract class
have changed and you will need to update your tests accordingly. Namely, it's discouraged to use __construct
and
__desctruct
methods. setUp
and tearDown
have been marked as private and are used for consistent test
boostrapping and asserting pre and post conditions, your test case should use up
and down
methods instead.
Simpletests can no longer be executed from the admin interface of the developers plugin.
Use Elgg cli command: elgg-cli simpletest