H4 Conversion HowTo Authentication Autoloading Class naming CLI Configuration files Convert Base files Convert to PHP 5 CVS remnants Constants Documentation Database Error Handling Globals Header templates Hooks Images/Graphics Initialization Injector Usage Javascript Log handling Mail library Menu MIME library NLS/Language/Charset handling Output buffering PEAR_Error Prefs UI Sidebar integration Test script Themes Translations Horde_Ui Url generation H4 Conversion HowTo Items that need to be converted... Authentication Remove AUTH_HANDLER - use Horde_Registry::appInit() 'authentication' option instead. Remove $session_control - use Horde_Registry::appInit() 'session_control' option instead Most static Horde_Auth:: functions moved to Horde_Registry:: Horde_Auth::getAuth() -> $registry->getAuth() Horde_Auth::getBareAuth() -> $registry->getAuth('bare') Horde_Auth::getAuthDomain() -> $registry->getAuth('domain') Horde_Auth::getOriginalAuth() -> $registry->getAuth('original') Horde_Auth::getCredential() -> $registry->getAuthCredential() Horde_Auth::isAdmin() -> $registry->isAdmin() Horde_Auth::addHook($user) -> $registry->convertUsername($user, true) Horde_Auth::removeHook($user) -> $registry->convertUsername($user, false) Autoloading Convert files/libraries to be able to be autoloaded. Remove require/include calls within the code. Class naming All (framework) classes must be prefixed with Horde_ to allow autoloading of the files. When converting from Horde 3 format (e.g. Foo class) to Horde 4 format (e.g. Horde_Foo), the following commands are useful to convert all files automatically: find . -type f \( ! -wholename "./.git/*" ! -name "CHANGES" \) | xargs grep -l '[] (!)]Foo::' | xargs sed -i -r -e 's/([\ \(\^\!\)])Foo::/\1Horde_Foo::/g' find . -type f \( ! -wholename "./.git/*" ! -name "CHANGES" \) | xargs grep -l '&Foo::' | xargs sed -i -r -e 's/&Foo::/Horde_Foo::/g' find . -type f \( ! -wholename "./.git/*" ! -name "CHANGES" \) | xargs grep -l '^Foo::' | xargs sed -i -r -e 's/^Foo::/Horde_Foo::/g' CLI Use Horde_Registry::appInit(), with the 'cli' option, to initialize CLI scripts. Configuration files Add $Id$ tag to all conf/*.xml files Convert Base files No more lib/base.php, lib/api.php, lib/version.php. Converted to lib/Application.php and lib/Api.php Convert to PHP 5 TODO instanceof instead of is_a() CVS remnants No need for $Horde$ in header comments. Remove CVS directories. Remove .cvsignore Constants Constants should be namespaced - preferably within the utility class (e.g. lib/App.php). Documentation Update documentation. Database All database abstraction is done through the Horde_Db library now. SQL scripts from scripts/sql/ need to be converted to Horde_Db migrations in migration/. Cheat sheet for converting PEAR::DB calls to Horde_Db calls: +---------------------------------+------------------------------------+ |PEAR DB |Horde_Db | +=================================+====================================+ |select()/query() |execute()/insert()/update()/delete()| +---------------------------------+------------------------------------+ |getAll() (w/DB_FETCHMODE_ORDERED)|?? | +---------------------------------+------------------------------------+ |getAll() (w/DB_FETCHMODE_ASSOC) |selectAll() | +---------------------------------+------------------------------------+ |getAssoc() |selectAssoc() (only with 2 columns) | +---------------------------------+------------------------------------+ |getCol() |selectValues() | +---------------------------------+------------------------------------+ |getOne() |selectValue() | +---------------------------------+------------------------------------+ |getRow() |selectOne() | +---------------------------------+------------------------------------+ |setLimit() |addLimitOffset() | +---------------------------------+------------------------------------+ select() return a statement object from the SQL query. Error Handling Don't use Horde::fatal() directly - throw an Exception and if uncaught, a fatal exception handler will be triggered. Globals Remove all use of globals within the application (use injector instead). Header templates Most applications should no longer need a custom header template. Instead use: require $registry->get('templates', 'horde') . '/common-header.inc'; Hooks Hooks are methods of an App_Hooks class in config/hook.php.dist now. They are called different too: try { Horde::callHook('hookname', array($arg1, $arg2, ...), 'applicationname'); } catch (Horde_Exception_HookNotSet $e) { } If the hook is supposed to be called often, it should be checked if the code exists with Horde::hookExists() instead of catching the Horde_Exception_HookNotSet exception. Images/Graphics OLD: $registry->getImageDir() . '/image.png'; NEW: Horde_Themes::img('image.png'); Note that if you want to prevent using images from Horde itself and always use the current application, use the following: Horde_Themes::img('image.png'), array('nohorde' => true)); Also note this policy change from H3: "Do note that doing something like grabbing an image dir and then manually appending various image names to it is NOT supported in H4." Generating tags of non-static images, e.g. the script files from horde/services/images/ through Horde::img() is not supported anymore. Initialization Controller scripts are now initialized by: require_once dirname(__FILE__) . '/lib/Application.php'; Horde_Registry::appInit('appname'); Injector Usage Various Horde libraries now must be loaded via the injector. Javascript ALL javascript should be in js/. NO javscript (if at all possible) should be contained in scripts/templates. Log handling Log constants have changed: we no longer use the PEAR constants and instead use strings to indicate the severity. Also note the function signature no longer requires the file name or line number. OLD: Horde::logMessage("Something broke", __FILE__, __LINE__, PEAR_LOG_ERR); NEW: Horde::logMessage("Something broke", 'ERR'); Mail library PEAR's Mail library has been replaced by Horde_Mail. Menu The menu should be provided now by Appname_Application::menu(). templates/menu.inc can be removed, unless there are any custom elements. To render the menu use: echo Horde::menu(); $notification->notify(array('listeners' => 'status')); MIME library The MIME library has been rewritten - most calls to the library will probably need to be changed. NLS/Language/Charset handling Most/all language and/or charset handling has been moved to Horde_Registry. See http://bugs.horde.org/ticket/9124#c8. Output buffering Convert from Util::bufferOutput() -> Horde::startBuffer()/Horde::endBuffer() PEAR_Error Remove PEAR_Error usage - convert to Exceptions. Each application should define a APP_Exception library that extends Horde_Exception. Prefs UI No more lib/prefs.php - now uses Horde_Registry_Application calls. Update config/prefs.php to remove unneeded entries. Sidebar integration The sidebar menu is no longer in a separate frame. To integrate with all pages of your application, put the following code after your menu, e.g. at the bottom of templates/menu.inc, but before the notification output: if (!Horde_Util::getFormData('ajaxui')) require HORDE_BASE . '/services/sidebar.php'; Test script No longer uses test.php - converted to lib/Test.php. Themes TODO Translations All translations and help files have to be encoded in UTF-8 now. Translation files have been renamed and moved to the locale/ directories. imp/po/de_DE.po is now in imp/locale/de/LC_MESSAGES/imp.po. Horde_Ui Horde_Ui_* classes are now Horde_Core_Ui_* Url generation Use Horde::url() instead of Horde::applicationUrl(). Use Horde_Url:: instead of Horde_Util::addParameter()/Horde_Util::removeParameter().