.. contents:: Contents .. section-numbering:: ====================== 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().