From 2.x to 3.0
Contents
PHP 7.0 is now required
5.6 is reaching it’s end of life. PHP 7.0 is now required to install and run Elgg.
$CONFIG
is removed!
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.
Removed views
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 behaviour
input/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 user
pages/icon
groups/group_sort_menu
: useregister, filter:menu:groups/all
plugin hook
groups/my_status
groups/profile/stats
subscriptions/form/additions
: extendnotifications/settings/other
instead
likes/count
: modifications can now be done to thelikes_count
menu item
likes/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 items
river/user/default/profileupdate
admin.js
aalborg_theme/homepage.png
aalborg_theme/css
resources/avatar/view
: Use entity icon API
ajax_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 hook
navigation/menu/site
: now uses default view
page/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 River
river/object/page/create
: check River
river/object/page_top/create
: check River
river/relationship/member
: check River
object/page_top
: useobject/page
ajax/discussion/reply/edit
: See Discussion replies moved to comments
discussion/replies
: See Discussion replies moved to comments
object/discussion_reply
: See Discussion replies moved to comments
resources/discussion/reply/edit
: See Discussion replies moved to comments
resources/elements/discussion_replies
: See Discussion replies moved to comments
river/elements/discussion_replies
: See Discussion replies moved to comments
river/object/discussion/create
river/object/discussion_reply/create
: See Discussion replies moved to comments
search/object/discussion_reply/entity
: See Discussion replies moved to comments
rss/discussion/replies
: See Discussion replies moved to comments
search/header
search/layout
in bothdefault
andrss
viewtypes
search/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
Removed functions/methods
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 plugins
elgg_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
hook
groups_register_profile_buttons
: Useregister, menu:title
hook
groups_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
interface
system_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
hooks
elgg_check_access_overrides
AttributeLoader
became obsolete and was removed
Application::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 read
ElggData::getClassName
: Useget_class()
ElggData::set
: Usually can be replaced by property write
ElggEntity::setURL
: SeegetURL
for details on the plugin hook
ElggMenuBuilder::compareByWeight
: UsecompareByPriority
ElggMenuItem::getWeight
: UsegetPriority
ElggMenuItem::getContent
: Useelgg_view_menu_item()
ElggMenuItem::setWeight
: UsesetPriority
ElggRiverItem::getPostedTime
: UsegetTimePosted
ElggSession
has removed all deprecated methods
ElggSite::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 directly
ElggSite::checkWalledGarden
: Logic moved to the router and should not be accessed directly
ElggUser::countObjects
: Useelgg_get_entities()
Logger::getClassName
: Useget_class()
Elgg\Application\Database::getTablePrefix
: Read theprefix
property
elgg_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 Discussion replies moved to comments
discussion_can_edit_reply
: See Discussion replies moved to comments
discussion_reply_menu_setup
: See Discussion replies moved to comments
discussion_reply_container_logic_override
: See Discussion replies moved to comments
discussion_reply_container_permissions_override
: See Discussion replies moved to comments
discussion_update_reply_access_ids
: See Discussion replies moved to comments
discussion_search_discussion
: See Discussion replies moved to comments
discussion_add_to_river_menu
: See Discussion replies moved to comments
discussion_prepare_reply_notification
: See Discussion replies moved to comments
discussion_redirect_to_reply
: See Discussion replies moved to comments
discussion_ecml_views_hook
: See Discussion replies moved to comments
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
Deprecated APIs
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()
Removed global vars
$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
Removed classes/interfaces
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 Discussion replies moved to comments
Schema changes
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).
Changes in elgg_get_entities
, elgg_get_metadata
and elgg_get_annotations
getter functions
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.
Boolean entity properties
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 Changes
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.
Permissions and Access
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.
Multi Site Changes
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.
Entity Subtable Changes
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.
Friends and Group Access Collection
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
.
Subtypes no longer have an ID
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 users
group
for groups
site
for sites
Custom class loading
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
Dependency Injection Container
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.
Search changes
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 Search Service and Search hooks documentation for detailed information about new search capabilities.
Removed libraries
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.
Removed pagehandling
file/download
file/search
groupicon
twitterservice
collections/pickercallback
discussion/reply
: See Discussion replies moved to comments
expages
invitefriends
: Usefriends/{username}/invite
messages/compose
: Usemessages/add
reportedcontent
Removed actions
file/download
: Useelgg_get_inline_url
orelgg_get_download_url
file/delete
: Useentity/delete
action
import/opendd
discussion/reply/save
: See Discussion replies moved to comments
discussion/reply/delete
: See Discussion replies moved to comments
comment/delete
: Useentity/delete
action
uservalidationbyemail/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
Inheritance changes
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
Removed JavaScript APIs
admin.js
elgg.widgets
: Use theelgg/widgets
module. The “widgets” layouts do this module automatically
lightbox.js
: Use theelgg/lightbox
module as needed
lightbox/settings.js
: Use thegetOptions, ui.lightbox
JS hook or thedata-colorbox-opts
attribute
elgg.ui.popupClose
: Use theelgg/popup
module
elgg.ui.popupOpen
: Use theelgg/popup
module
elgg.ui.initAccessInputs
elgg.ui.river
elgg.ui.initDatePicker
: Use theinput/date
module
elgg.ui.likesPopupHandler
elgg.embed
: Use theelgg/embed
module
elgg.discussion
: Use theelgg/discussion
module
embed/custom_insert_js
: Use theembed, editor
JS hook
elgg/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 automatically
messageboard.js
elgg.autocomplete
is no longer defined.
elgg.messageboard
is no longer defined.
jQuery.fn.friendsPicker
elgg.ui.toggleMenu
is no longer defined
elgg.ui.toggleMenuItems
: Usedata-toggle
attribute when registering toggleable menu items
uservalidationbyemail/js.php
: Use theelgg/uservalidationbyemail
module
discussion.js
: See Discussion replies moved to comments
Removed hooks/events
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
viewHook 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
Removed forms/actions
notificationsettings/save
form and action
notificationsettings/groupsave
form and action
discussion/reply/save
form and action
APIs that now accept only an $options
array
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
Plugin functions that now require an explicit $plugin_id
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
Class constructors that now accept only a stdClass
object or null
ElggAnnotation
: No longer accepts an annotation ID
ElggGroup
: No longer accepts a GUID
ElggMetadata
: No longer accepts a metadata ID
ElggObject
: No longer accepts a GUID
ElggRelationship
: No longer accepts a relationship ID ornull
ElggSite
: No longer accepts a GUID or URL
ElggUser
: No longer accepts a GUID or username
ElggPlugin
: No longer accepts a GUID or path. UseElggPlugin::fromId
to construct a plugin from its path
Miscellaneous API changes
ElggBatch
: You may only access public properties
ElggEntity
: Thetables_split
andtables_loaded
properties were removed
ElggEntity
: Empty URLs will no longer be normalized. This means entities without URLs will no longer result in the site URL
ElggGroup::removeObjectFromGroup
requires passing in anElggObject
(no longer accepts a GUID)
ElggUser::$salt
no longer exists as an attribute, nor is it used for authentication
ElggUser::$password
no longer exists as an attribute, nor is it used for authentication
elgg_get_widget_types
no longer supports$exact
as the 2nd argument
elgg_instanceof
no longer supports the fourthclass
argument
elgg_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 argument
elgg_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 size
ElggEntity::saveIconFromLocalFile
only saves master size, the other sizes are created when requested byElggEntity::getIcon()
based on the master size
ElggEntity::saveIconFromElggFile
only saves master size, the other sizes are created when requested byElggEntity::getIcon()
based on the master sizeGroup entities do no longer have the magic
username
attribute.Pagehandling will no longer detect
group:<guid>
in the URLThe 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
View extension behaviour changed
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.
JavaScript hook calling order may change
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.
Routing
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 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.
Labelling
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.
Request value filtering
set_input()
and get_input()
no longer trim values.
Action responses
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.
HtmLawed is no longer a plugin
Do not call
elgg_load_library('htmlawed')
.In the hook params for
'config', 'htmlawed'
, thehook_tag
function name changed.
New approach to page layouts
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 renderedlayout 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
layoutUpdate replace
nav
parameter in layout views withbreadcrumbs
parameterUpdate their use of
filter
parameter in layout views by either providing a default set of filter tabs, or setting afilter_id
parameter and using hooksRemove
page/layouts/one_column
viewRemove
page/layouts/one_sidebar
viewRemove
page/layouts/two_sidebar
viewRemove
page/layouts/content
viewUpdate 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 plugin
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
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.
Pages plugin
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
.
Profile plugin
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.
Data Views plugin
The Data Views plugin no longer comes bundled.
Twitter API plugin
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"
}
}
Legacy URLs plugin
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"
}
}
User validation by email plugin
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.
Email delivery
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.
Theme and styling changes
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 itemsSupport for
.elgg-icon-hover
has been droppedUser “hover” icons are no longer covered with a “caret” icon
Read more about Theming Principles
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
.
Object listing views
object/elements/full/body
now wraps the full listing body in a.elgg-listing-full-body
wrapper
object/elements/full
now supportsattachments
andresponses
which are rendered after listing bodyIn 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
view
object/file
now passes image (specialcontent) view as anattachment
to the full listing view
Entity icons
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.
Icon glyphs
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).
Autocomplete (user and friends pickers)
Friends Picker input is now rendered using input/userpicker
.
Plugins should:
Update overriden
input/userpicker
to support newonly_friends
parameterRemove friends picker CSS from their stylesheets
Friends collections
Friends collections UI has been moved to its own plugins - friends_collections
.
Layout of .elgg-body
elements
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
.
Delete river items
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
Discussion replies moved to comments
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.
Translations cleanup
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
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.
Error logging
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.
Composer asset plugin no longer required
Assets are now loaded from https://asset-packagist.org. FXP composer asset plugin is no longer required when installing Elgg or updating composer dependencies.
Cron logs
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.
Removed / changed language keys
The language keys related to comment notifications have changed. Check the
generic_comment:notification:owner:
language keys
New MySQL schema features are not applied
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).
Miscellaneous changes
The settings “Allow visitors to register” and “Restrict pages to logged-in users” now appear on the Basic Settings admin page.
Twitter API plugin
The twitter_api
plugin no longer comes bundled with Elgg.
Unit and Integration Testing
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
Comments
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.