\documentclass{article}
\usepackage{ulem}
\usepackage{graphicx}
\usepackage{hyperref}
\pagestyle{headings}
\begin{document}
\part{H4 Conversion HowTo}
Items that need to be converted...

\section{Authentication}
Remove AUTH\_HANDLER - use Horde\_Registry::appInit() 'authentication' option instead.<br />
Remove \$session\_control - use Horde\_Registry::appInit() 'session\_control' option instead<br />
Most static Horde\_Auth:: functions moved to Horde\_Registry::

\begin{quote}
Horde\_Auth::getAuth() -> \$registry->getAuth()<br />
Horde\_Auth::getBareAuth() -> \$registry->getAuth('bare')<br />
Horde\_Auth::getAuthDomain() -> \$registry->getAuth('domain')<br />
Horde\_Auth::getOriginalAuth() -> \$registry->getAuth('original')<br />
Horde\_Auth::getCredential() -> \$registry->getAuthCredential()<br />
Horde\_Auth::isAdmin() -> \$registry->isAdmin()<br />
Horde\_Auth::addHook(\$user) -> \$registry->convertUsername(\$user, true)<br />
Horde\_Auth::removeHook(\$user) -> \$registry->convertUsername(\$user, false)


\end{quote}
\section{Autoloading}
Convert files/libraries to be able to be autoloaded.<br />
Remove require/include calls within the code.

\section{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:

<pre><code>
find . -type f \textbackslash\{\}( ! -wholename "./.git/*" ! -name "CHANGES" \textbackslash\{\}) | xargs grep -l '[] (!)]Foo::' | xargs sed -i -r -e 's/([\textbackslash\{\} \textbackslash\{\}(\textbackslash\{\}\^{}\textbackslash\{\}!\textbackslash\{\})])Foo::/\textbackslash\{\}1Horde\_Foo::/g'
find . -type f \textbackslash\{\}( ! -wholename "./.git/*" ! -name "CHANGES" \textbackslash\{\}) | xargs grep -l '\&Foo::' | xargs sed -i -r -e 's/\&Foo::/Horde\_Foo::/g'
find . -type f \textbackslash\{\}( ! -wholename "./.git/*" ! -name "CHANGES" \textbackslash\{\}) | xargs grep -l '\^{}Foo::' | xargs sed -i -r -e 's/\^{}Foo::/Horde\_Foo::/g'
</code></pre>
\section{CLI}
Use Horde\_Registry::appInit(), with the 'cli' option, to initialize CLI scripts.

\section{Configuration files}
Add \$Id\$ tag to all conf/*.xml files

\section{Convert Base files}
No more lib/base.php, lib/api.php, lib/version.php.  Converted to lib/Application.php and lib/Api.php

\section{Convert to PHP 5}
TODO<br />
instanceof instead of is\_a()

\section{CVS remnants}
No need for \$Horde\$ in header comments.<br />
Remove CVS directories.<br />
Remove .cvsignore

\section{Constants}
Constants should be namespaced - preferably within the utility class (e.g. lib/App.php).

\section{Documentation}
Update documentation.

\section{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:

<table class="horde-table">PEAR DB & Horde\_Db \\
\hline
select()/query() & execute()/insert()/update()/delete() \\
\hline
getAll() (w/DB\_FETCHMODE\_ORDERED) & ?? \\
\hline
getAll() (w/DB\_FETCHMODE\_ASSOC) & selectAll() \\
\hline
getAssoc() & selectAssoc() (only with 2 columns) \\
\hline
getCol() & selectValues() \\
\hline
getOne() & selectValue() \\
\hline
getRow() & selectOne() \\
\hline
setLimit() & addLimitOffset() \\
\hline
</table>
select() return a statement object from the SQL query.

\section{Error Handling}
Don't use Horde::fatal() directly - throw an Exception and if uncaught, a fatal exception handler will be triggered.

\section{Globals}
Remove all use of globals within the application (use injector instead).

\section{Header templates}
Most applications should no longer need a custom header template. Instead use:

<pre><code class="language-php">
require \$registry->get('templates', 'horde') . '/common-header.inc';
</code></pre>
\section{Hooks}
Hooks are methods of an App\_Hooks class in config/hook.php.dist now. They are called different too:

<pre><code class="language-php">
try \{
    Horde::callHook('hookname', array(\$arg1, \$arg2, ...), 'applicationname');
\} catch (Horde\_Exception\_HookNotSet \$e) \{
\}
</code></pre>
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.

\section{Images/Graphics}
OLD:

<pre><code>
\$registry->getImageDir() . '/image.png';
</code></pre>
NEW:

<pre><code>
Horde\_Themes::img('image.png');
</code></pre>
Note that if you want to prevent using images from Horde itself and always use the current application, use the following:

<pre><code>
Horde\_Themes::img('image.png'), array('nohorde' => true));
</code></pre>
Also note this policy change from H3:<br />
"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 <img> tags of non-static images, e.g. the script files from horde/services/images/ through Horde::img() is not supported anymore.

\section{Initialization}
Controller scripts are now initialized by:

<pre><code class="language-php">
require\_once dirname(\_\_FILE\_\_) . '/lib/Application.php';
Horde\_Registry::appInit('appname');
</code></pre>
\section{Injector Usage}
Various Horde libraries now must be loaded via the injector.

\section{Javascript}
ALL javascript should be in js/.  NO javscript (if at all possible) should be contained in scripts/templates.

\section{Log handling}
Log constants have changed: we no longer use the PEAR constants and instead use strings to indicate the severity.<br />
Also note the function signature no longer requires the file name or line number.

OLD:

<pre><code>
Horde::logMessage("Something broke", \_\_FILE\_\_, \_\_LINE\_\_, PEAR\_LOG\_ERR);
</code></pre>
NEW:

<pre><code>
Horde::logMessage("Something broke", 'ERR');
</code></pre>
\section{Mail library}
PEAR's Mail library has been replaced by Horde\_Mail.

\section{Menu}
The menu should be provided now by Appname\_Application::menu(). \texttt{templates/menu.inc} can be removed, unless there are any custom elements. To render the menu use:

<pre><code class="language-php">
echo Horde::menu();
\$notification->notify(array('listeners' => 'status'));
</code></pre>
\section{MIME library}
The MIME library has been rewritten - most calls to the library will probably need to be changed.

\section{NLS/Language/Charset handling}
Most/all language and/or charset handling has been moved to Horde\_Registry.  See <a href="http://bugs.horde.org/ticket/9124#c8">http://bugs.horde.org/ticket/9124\#c8</a>.

\section{Output buffering}
Convert from Util::bufferOutput() -> Horde::startBuffer()/Horde::endBuffer()

\section{PEAR\_Error}
Remove PEAR\_Error usage - convert to Exceptions.<br />
Each application should define a APP\_Exception library that extends Horde\_Exception.

\section{Prefs UI}
No more lib/prefs.php - now uses Horde\_Registry\_Application calls.<br />
Update config/prefs.php to remove unneeded entries.

\section{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:

<pre><code class="language-php">
if (!Horde\_Util::getFormData('ajaxui')) require HORDE\_BASE . '/services/sidebar.php';
</code></pre>
\section{Test script}
No longer uses test.php - converted to lib/Test.php.

\section{Themes}
TODO

\section{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.

\section{Horde\_Ui}
Horde\_Ui\_* classes are now Horde\_Core\_Ui\_*

\section{Url generation}
Use Horde::url() instead of Horde::applicationUrl().<br />
Use Horde\_Url:: instead of Horde\_Util::addParameter()/Horde\_Util::removeParameter().

\end{document}
