From 1.x to 2.0¶
Contents
- Elgg can be now installed as a composer dependency instead of at document root
- Cacheable views must have a file extension in their names
- Dropped
jquery-migrate
and upgradedjquery
to ^2.1.4 - JS and CSS views have been moved out of the js/ and css/ directories
fxp/composer-asset-plugin
is now required to install Elgg from source- List of deprecated views and view arguments that have been removed
- All scripts moved to bottom of page
- Attribute formatter removes keys with underscores
- Breadcrumbs
- Callbacks in Queries
- Comments plugin hook
- Container permissions hook
- Creating or deleting a relationship triggers only one event
- Discussion feature has been pulled from groups into its own plugin
- Dropped login-over-https feature
- Elgg has migrated from ext/mysql to PDO MySQL
- Event/Hook calling order may change
export/
URLs are no longer available- Icons migrated to Font Awesome
- Increase of z-index value in elgg-menu-site class
- input/autocomplete view
- Introduced third-party library for sending email
- Label elements
- Plugin Aalborg Theme
- Plugin Likes
- Plugin Messages
- Plugin Blog
- Plugin Bookmarks
- Plugin File
- Removed Classes
- Removed keys available via
elgg_get_config()
- Removed Functions
- Removed methods
- Removed Plugin Hooks
- Removed Actions
- Removed Views
- Removed View Variables
- Removed libraries
- Specifying View via Properties
- Viewtype is static after the initial
elgg_get_viewtype()
call - Deprecations
Elgg can be now installed as a composer dependency instead of at document root¶
That means an Elgg site can look something like this:
settings.php
vendor/
elgg/
elgg/
engine/
start.php
_graphics/
elgg_sprites.png
mod/
blog
bookmarks
...
elgg_get_root_path
and $CONFIG->path
will return the path to the application
root directory, which is not necessarily the same as Elgg core’s root directory (which
in this case is vendor/elgg/elgg/
).
Do not attempt to access the core Elgg from your plugin directly, since you cannot rely on its location on the filesystem.
In particular, don’t try load engine/start.php
.
// Don't do this!
dirname(__DIR__) . "/engine/start.php";
To boot Elgg manually, you can use the class Elgg\Application
.
// boot Elgg in mod/myplugin/foo.php
require_once dirname(dirname(__DIR__)) . '/vendor/autoload.php';
\Elgg\Application::start();
However, use this approach sparingly. Prefer Routing instead whenever possible as that keeps your public URLs and your filesystem layout decoupled.
Also, don’t try to access the _graphics
files directly.
readfile(elgg_get_root_path() . "_graphics/elgg_sprites.png");
Use Views instead:
echo elgg_view('elgg_sprites.png');
Cacheable views must have a file extension in their names¶
This requirement makes it possibile for us to serve assets directly from disk for performance, instead of serving them through PHP.
It also makes it much easier to explore the available cached resources by navigating to dataroot/views_simplecache and browsing around.
- Bad:
my/cool/template
- Good:
my/cool/template.html
We now cache assets by "$viewtype/$view"
, not md5("$viewtype|$view")
,
which can result in conflicts between cacheable views that don’t have file extensions
to disambiguate files from directories.
Dropped jquery-migrate
and upgraded jquery
to ^2.1.4¶
jQuery 2.x is API-compatible with 1.x, but drops support for IE8-, which Elgg hasn’t supported for some time anyways.
See http://jquery.com/upgrade-guide/1.9/ for how to move off jquery-migrate.
If you’d prefer to just add it back, you can use this code in your plugin’s init:
elgg_register_js('jquery-migrate', elgg_get_simplecache_url('jquery-migrate.js'), 'head');
elgg_load_js('jquery-migrate');
Also, define a jquery-migrate.js
view containing the contents of the script.
JS and CSS views have been moved out of the js/ and css/ directories¶
They also have been given .js and .css extensions respectively if they didn’t already have them:
Old view | New view |
---|---|
js/view |
view.js |
js/other.js |
other.js |
css/view |
view.css |
css/other.css |
other.css |
js/img.png |
img.png |
The main benefit this brings is being able to co-locate related assets.
So a template (view.php
) can have its CSS/JS dependencies right next to it
(view.css
, view.js
).
Care has been taken to make this change as backwards-compatible as possible, so you should not need to update any view references right away. However, you are certainly encouraged to move your JS and CSS views to their new, canonical locations.
Practically speaking, this carries a few gotchas:
The view_vars, $view_name
and view, $view_name
hooks will operate on the
canonical view name:
elgg_register_plugin_hook_handler('view', 'css/elgg', function($hook, $view_name) {
assert($view_name == 'elgg.css') // not "css/elgg"
});
Using the view, all
hook and checking for individual views may not work as intended:
elgg_register_plugin_hook_handler('view', 'all', function($hook, $view_name) {
// Won't work because "css/elgg" was aliased to "elgg.css"
if ($view_name == 'css/elgg') {
// Never executed...
}
// Won't work because no canonical views start with css/* anymore
if (strpos($view_name, 'css/') === 0) {
// Never executed...
}
});
Please let us know about any other BC issues this change causes. We’d like to fix as many as possible to make the transition smooth.
fxp/composer-asset-plugin
is now required to install Elgg from source¶
We use fxp/composer-asset-plugin
to manage our browser assets (js, css, html)
with Composer, but it must be installed globally before installing Elgg in order
for the bower-asset/*
packages to be recognized. To install it, run:
composer global require fxp/composer-asset-plugin
If you don’t do this before running composer install
or composer create-project
,
you will get an error message:
[InvalidArgumentException]
Package fxp/composer-asset-plugin not found
List of deprecated views and view arguments that have been removed¶
We dropped support for and/or removed the following views:
- canvas/layouts/*
- categories
- categories/view
- core/settings/tools
- embed/addcontentjs
- footer/analytics (Use page/elements/foot instead)
- groups/left_column
- groups/right_column
- groups/search/finishblurb
- groups/search/startblurb
- input/calendar (Use input/date instead)
- input/datepicker (Use input/date instead)
- input/pulldown (Use input/select instead)
- invitefriends/formitems
- js/admin (Use AMD and
elgg_require_js
instead of extending JS views)- js/initialise_elgg (Use AMD and
elgg_require_js
instead of extending JS views)- members/nav
- metatags (Use the “head”, “page” plugin hook instead)
- navigation/topbar_tools
- navigation/viewtype
- notifications/subscriptions/groupsform
- object/groupforumtopic
- output/calendar (Use output/date instead)
- output/confirmlink (Use output/url instead)
- page_elements/contentwrapper
- page/elements/shortcut_icon (Use the “head”, “page” plugin hook instead)
- page/elements/wrapper
- profile/icon (Use
elgg_get_entity_icon
)- river/object/groupforumtopic/create
- settings/{plugin}/edit (Use plugins/{plugin}/settings instead)
- user/search/finishblurb
- user/search/startblurb
- usersettings/{plugin}/edit (Use plugins/{plugin}/usersettings instead)
- widgets/{handler}/view (Use widgets/{handler}/content instead)
We also dropped the following arguments to views:
- « value » in output/iframe (Use « src » instead)
- « area2 » and « area3 » in page/elements/sidebar (Use « sidebar » or view extension instead)
- « js » in icon views (e.g. icon/user/default)
- « options » to input/radio and input/checkboxes which aren’t key-value pairs will no longer be acceptable.
All scripts moved to bottom of page¶
You should test your plugin with the JavaScript error console visible. For performance reasons, Elgg no longer
supports script
elements in the head
element or in HTML views. elgg_register_js
will now load all
scripts at the end of the body
element.
You must convert inline scripts to AMD or to external scripts loaded with
elgg_load_js
.
Early in the page, Elgg provides a shim of the RequireJS require()
function that simply queues code until
the AMD elgg
and jQuery
modules are defined. This provides a straightforward way to convert many inline
scripts to use require()
.
Inline code which will fail because the stack is not yet loaded:
<script>
$(function () {
// code using $ and elgg
});
</script>
This should work in Elgg 2.0:
<script>
require(['elgg', 'jquery'], function (elgg, $) {
$(function () {
// code using $ and elgg
});
});
</script>
Attribute formatter removes keys with underscores¶
elgg_format_attributes()
(and all APIs that use it) now filter out attributes whose name contains an
underscore. If the attribute begins with data-
, however, it will not be removed.
Breadcrumbs¶
Breadcrumb display now removes the last item if it does not contain a link. To restore the previous behavior,
replace the plugin hook handler elgg_prepare_breadcrumbs
with your own:
elgg_unregister_plugin_hook_handler('prepare', 'breadcrumbs', 'elgg_prepare_breadcrumbs');
elgg_register_plugin_hook_handler('prepare', 'breadcrumbs', 'myplugin_prepare_breadcrumbs');
function myplugin_prepare_breadcrumbs($hook, $type, $breadcrumbs, $params) {
// just apply excerpt to titles
foreach (array_keys($breadcrumbs) as $i) {
$breadcrumbs[$i]['title'] = elgg_get_excerpt($breadcrumbs[$i]['title'], 100);
}
return $breadcrumbs;
}
Callbacks in Queries¶
Make sure to use only valid callable values for « callback » argument/options in the API.
Querying functions will now will throw a RuntimeException
if is_callable()
returns false
for the given
callback value. This includes functions such as elgg_get_entities()
, get_data()
, and many more.
Comments plugin hook¶
Plugins can now return an empty string from 'comments',$entity_type
hook in order to override the default comments component view. To force the default comments component, your plugin must return false
. If you were using empty strings to force the default comments view, you need to update your hook handlers to return false
.
Container permissions hook¶
The behavior of the container_permissions_check
hook has changed when an entity is being created: Before 2.0, the hook would be called twice if the entity’s container was not the owner. On the first call, the entity’s owner would be passed in as $params['container']
, which could confuse handlers.
In 2.0, when an entity is created in a container like a group, if the owner is the same as the logged in user (almost always the case), this first check is bypassed. So the container_permissions_check
hook will almost always be called once with $params['container']
being the correct container of the entity.
Creating or deleting a relationship triggers only one event¶
The « create » and « delete » relationship events are now only fired once, with "relationship"
as the object type.
E.g. Listening for the "create", "member"
or "delete", "member"
event(s) will no longer capture group membership additions/removals. Use the "create", "relationship"
or "delete", "relationship"
events.
Discussion feature has been pulled from groups into its own plugin¶
The object, groupforumtopic
subtype has been replaced with the
object, discussion
subtype. If your plugin is using or altering
the old discussion feature, you should upgrade it to use the new
subtype.
Nothing changes from the group owners” point of view. The discussion feature is still available as a group tool and all old discussions are intact.
Dropped login-over-https feature¶
For the best security and performance, serve all pages over HTTPS by switching
the scheme in your site’s wwwroot to https
at http://yoursite.tld/admin/settings/advanced
Elgg has migrated from ext/mysql to PDO MySQL¶
Elgg now uses a PDO_MYSQL
connection and no longer uses any ext/mysql functions. If you use
mysql_*
functions, implicitly relying on an open connection, these will fail.
If your code uses one of the following functions, read below.
execute_delayed_write_query()
execute_delayed_read_query()
If you provide a callable $handler
to be called with the results, your handler will now receive a
\Doctrine\DBAL\Driver\Statement
object. Formerly this was an ext/mysql result
resource.
Event/Hook calling order may change¶
When registering for events/hooks, the all
keyword for wildcard matching no longer has any effect
on the order that handlers are called. To ensure your handler is called last, you must give it the
highest priority of all matching handlers, or to ensure your handler is called first, you must give
it the lowest priority of all matching handlers.
If handlers were registered with the same priority, these are called in the order they were registered.
To emulate prior behavior, Elgg core handlers registered with the all
keyword have been raised in
priority. Some of these handlers will most likely be called in a different order.
export/
URLs are no longer available¶
Elgg no longer provides this endpoint for exposing resource data.
Icons migrated to Font Awesome¶
Elgg’s sprites and most of the CSS classes beginning with elgg-icon-
have been removed.
Usage of elgg_view_icon()
is backward compatible, but static HTML using the elgg-icon
classes will have to be updated to the new markup.
input/autocomplete view¶
Plugins that override the input/autocomplete
view will need to include the source URL in the data-source
attribute of the input element, require the new elgg/autocomplete
AMD module, and call its init
method. The 1.x javascript library elgg.autocomplete
is no longer used.
Introduced third-party library for sending email¶
We are using the excellent Zend\Mail
library to send emails in Elgg 2.0.
There are likely edge cases that the library handles differently than Elgg 1.x.
Take care to test your email notifications carefully when upgrading to 2.0.
Label elements¶
The following views received label
elements around some of the input fields. If your plugin/theme overrides these views please check for the new content.
- views/default/core/river/filter.php
- views/default/forms/admin/plugins/filter.php
- views/default/forms/admin/plugins/sort.php
- views/default/forms/login.php
Plugin Aalborg Theme¶
The view page/elements/navbar
now uses a Font Awesome icon for the mobile menu selector instead of an image. The bars.png
image and supporting CSS for the 1.12 rendering has been removed, so update your theme accordingly.
Plugin Likes¶
Objects are no longer likable by default. To support liking, you can register a handler to permit the annotation,
or more simply register for the hook ["likes:is_likable", "<type>:<subtype>"]
and return true. E.g.
elgg_register_plugin_hook_handler('likes:is_likable', 'object:mysubtype', 'Elgg\Values::getTrue');
Just as before, the permissions_check:annotate
hook is still called and may be used to override default behavior.
Plugin Messages¶
If you’ve removed or replaced the handler function messages_notifier
to hide/alter the inbox icon, you’ll instead need to do the
same for the topbar menu handler messages_register_topbar
. messages_notifier
is no longer used to add the menu link.
Messages will no longer get the metadata “msg” for newly created messages. This means you can not rely on that metadata to exist.
Plugin Blog¶
The blog pages showing “Mine” or “Friends” listings of blogs have been changed to list all the blogs owned by the users (including those created in groups).
Plugin Bookmarks¶
The bookmark pages showing “Mine” or “Friends” listings of bookmarks have been changed to list all the bookmarks owned by the users (including those created in groups).
Plugin File¶
The file pages showing “Mine” or “Friends” listings of files have been changed to list all the files owned by the users (including those created in groups).
Removed Classes¶
ElggInspector
Notable
FilePluginFile
: replace withElggFile
(or load withget_entity()
)
Removed keys available via elgg_get_config()
¶
allowed_ajax_views
dataroot_in_settings
externals
externals_map
i18n_loaded_from_cache
language_paths
pagesetupdone
registered_tag_metadata_names
simplecache_enabled_in_settings
translations
viewpath
views
view_path
viewtype
wordblacklist
Also note that plugins should not be accessing the global $CONFIG
variable except for in settings.php
.
Removed Functions¶
blog_get_page_content_friends
blog_get_page_content_read
count_unread_messages()
delete_entities()
delete_object_entity()
delete_user_entity()
elgg_get_view_location()
elgg_validate_action_url()
execute_delayed_query()
extend_view()
get_db_error()
get_db_link()
get_entities()
get_entities_from_access_id()
get_entities_from_access_collection()
get_entities_from_annotations()
get_entities_from_metadata()
get_entities_from_metadata_multi()
get_entities_from_relationship()
get_filetype_cloud()
get_library_files()
get_views()
is_ip_in_array()
list_entities()
list_entities_from_annotations()
list_group_search()
list_registered_entities()
list_user_search()
load_plugins()
menu_item()
make_register_object()
mysql_*()
: Elgg no longer uses ext/mysqlremove_blacklist()
search_for_group()
search_for_object()
search_for_site()
search_for_user()
search_list_objects_by_name()
search_list_groups_by_name()
search_list_users_by_name()
set_template_handler()
test_ip()
Removed methods¶
ElggCache::set_variable()
ElggCache::get_variable()
ElggData::initialise_attributes()
ElggData::getObjectOwnerGUID()
ElggDiskFilestore::make_directory_root()
ElggDiskFilestore::make_file_matrix()
ElggDiskFilestore::user_file_matrix()
ElggDiskFilestore::mb_str_split()
ElggEntity::clearMetadata()
ElggEntity::clearRelationships()
ElggEntity::clearAnnotations()
ElggEntity::getOwner()
ElggEntity::setContainer()
ElggEntity::getContainer()
ElggEntity::getIcon()
ElggEntity::setIcon()
ElggExtender::getOwner()
ElggFileCache::create_file()
ElggObject::addToSite()
: parent function in ElggEntity still availableElggObject::getSites()
: parent function in ElggEntity still availableElggSite::getCollections()
ElggUser::addToSite()
: parent function in ElggEntity still availableElggUser::getCollections()
ElggUser::getOwner()
ElggUser::getSites()
: parent function in ElggEntity still availableElggUser::listFriends()
ElggUser::listGroups()
ElggUser::removeFromSite()
: parent function in ElggEntity still available
The following arguments have also been dropped:
ElggSite::getMembers()
- 2:$offset
elgg_view_entity_list()
- 3:$offset
- 4:$limit
- 5:$full_view
- 6:$list_type_toggle
- 7:$pagination
Removed Plugin Hooks¶
[display, view]
: See the new plugin hook.
Removed Actions¶
widgets/upgrade
Removed Views¶
forms/admin/plugins/change_state
Removed View Variables¶
During rendering, the view system no longer injects these into the scope:
$vars['url']
: replace withelgg_get_site_url()
$vars['user']
: replace withelgg_get_logged_in_user_entity()
$vars['config']
: useelgg_get_config()
andelgg_set_config()
$CONFIG
: useelgg_get_config()
andelgg_set_config()
Also several workarounds for very old views are no longer performed. Make these changes:
- Set
$vars['full_view']
instead of$vars['full']
.- Set
$vars['name']
instead of$vars['internalname']
.- Set
$vars['id']
instead of$vars['internalid']
.
Removed libraries¶
elgg:markdown
: Elgg no longer provides a markdown implementation. You must provide your own.
Specifying View via Properties¶
The metadata $entity->view
no longer specifies the view used to render in elgg_view_entity()
.
Similarly the property $annotation->view
no longer has an effect within elgg_view_annotation()
.
Viewtype is static after the initial elgg_get_viewtype()
call¶
elgg_set_viewtype()
must be used to set the viewtype at runtime. Although Elgg still checks the
view
input and $CONFIG->view
initially, this is only done once per request.
Deprecations¶
It’s deprecated to read or write to metadata keys starting with filestore::
on ElggFile
objects. In Elgg 3.0 this metadata will be deleted if it points to the current data root path, so few file objects will have it. Plugins should only use ElggFile::setFilestore
if files need to be stored in a custom location.
Note
This is not the only deprecation in Elgg 2.0. Plugin developers should watch their site error logs.