Although this is a minor release following 2.2.5, there are a large number of breaking changes that developers must be aware of. The core team, along with the wonderful contributors, have been fixing, improving and tidying. The codebase is now neater, so that your extensions will be neater too.
Brendan has written a Migration Guide for 2.3 for Extension Developers which should list every core that that might affect your extensions. However this list is pretty long, so here is my summary. These are the steps I have followed for each extension to quickly fix the most common bugs.
extension.meta.xml
files replace the about()
function
Although not mandatory in 2.3, they are highly recommended. Add this file to the repo and remove the about()
function from your extension.driver.php
. Be sure that your XML file has the correct namespace!
<extension id="..." status="released" xmlns="http://www.getsymphony.com/schemas/extension/1.0">
Delete
delegate is no more
Search your source for Delete
(note the case) to see if you subscribe to this delegate. It has changed to EntryPreDelete
.
Accessing sym_pages
or sym_sections
directly?
If your extension queries these tables directly, then please stop. There is a good chance they will not exist in the future, in favour of other storage means. You must use the new PageManager
class or existing SectionManager
class as accessors. If you are modifying these tables by adding new columns, then this is very risky and you should store these in the config file instead. Don't say I didn't warn you.
displayDatasourceFilterPanel
markup change
If your field provides a displayDatasourceFilterPanel
method, the markup it provides has changed. It should now be:
<header>
<h4>Label</h4>
<span>Name</span>
</header>
So you can replace your code with:
$header = new XMLElement('header');
$header->appendChild(new XMLElement('h4', $this->get('label')));
$header->appendChild(new XMLElement('span', $this->name()));
$wrapper->appendChild($header);
processRawFieldData
arguments changed
The third argument for this method in your fields is now a $message
string and not $simulate
boolean. Be sure to add this new third argument (now five arguments, not four).
public function processRawFieldData($data, &$status, &$message=null, $simulate=false, $entry_id=null) {
buildDSRetrivalSQL
is deprecated
Spot the typo? The buildDSRetrivalSQL
method in your fields is deprecated and should be renamed buildDSRetrievalSQL
.
Delegate $context
no longer contains parent
In delegate callbacks, especially those that add CSS/JavaScript from the InitaliseAdminPageHead
delegate, the chances are you access the current page and check its context. Search for:
$context['parent']->Page
This no longer exists and you should use:
Administration::instance()->Page;
Equally, you should not request the _context
method on a page. Instead use the new getContext()
method:
// old
$page = $context['parent']->page;
$page_context = $page->_context['...'];
// new
$page = Administration::instance()->Page;
$context = $page->getContext();
$page_context = $context['...'];
Navigation groups can be aligned left or right
Symphony's navigation is now split left (content
) and right (structure
). If your extension adds a group to the navigation, be sure to specify which type
. For example:
array(
'name' => __('...'),
'type' => 'content',
'children' => array(...)
Managers are now static, _Parent
is no more
All managers are now static. You can leave them as they are, but we recommend using the new syntax since sharing the same manager instance can improve performance. Look familiar?
$sm = new SectionManager(Administration::instance());
$section = $sm->fetch(1);
Rewrite as:
$section = SectionManager::fetch(1);
This applies to SectionManager
, FieldManager
, EntryManager
as well as the others. You should search your code for _Parent
or _engine
for really old legacy code.
Database
and Configuration
accessors
The best way to get to the database and configuration objects is directly through the Symphony
class:
Symphony::Database()
Symphony::Configuration()
No need to pass $parent
to constructors
Most fields seem to have this passed in their constructors.
public function __construct(&$parent) {
...
parent::__construct($parent);
}
It's unnecessary and will throw an error:
Missing argument 1 for YourClass::__construct()
They can be removed.
Widget
values must be strings
Symphony is now more strict when it comes to building HTML form elements using the Widget
class. If your widget shows numbers, be sure to cast these as strings first:
$my_cache_value = 10;
Widget::Input('cache', (string)$my_cache_value);
Otherwise you'll get:
Symphony Fatal Error: Argument $value is not of type string, given integer.
Created tables must set charset
and collate
This is really important for multilingual compatibility. When creating new tables you must explicitly set the charset
and collate
, otherwise incorrect values might be inherited from MySQL's poor defaults. Search your code for create table
, and be sure you have something like:
ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Don't hard code /symphony
in URLs
Future versions of Symphony will allow developers to change the backend URL from /symphony
to their own choosing. When constructing URLs use the SYMPHONY_URL
constant:
$url = URL . '/symphony/...'; # bad
$url = SYMPHONY_URL . '/...'; # good
My own process
I rarely keep a single set of my extensions locally, since they all live remotely on Github. So to test them all against a new release I perform a mass-clone:
- Visit
http://symphonyextensions.com/export/ssh/:username
and copy the list of clone commands (replacessh
withgit
for read-only clone URLs, orsubmodule
for submodule commands instead) - Navigate to your extensions directory e.g.
cd ~/Sites/symphony-2/extensions
- Paste the clone commands and wait for all extensions to download
I then run through my list above performing a search across all files for various known terms (e.g. _Parent
to remove old accessors, new SectionManager
to find non-static SectionManager instances etc.)
This short term pain will have long term benefits for the whole community. So please, join me in updating our extensions for the best Symphony yet.