Abstract the Horde_Test interface.
authorMichael M Slusarz <slusarz@curecanti.org>
Fri, 8 Jan 2010 19:47:25 +0000 (12:47 -0700)
committerMichael M Slusarz <slusarz@curecanti.org>
Fri, 8 Jan 2010 19:47:25 +0000 (12:47 -0700)
Allows for easier maintenance of test scripts in the Horde apps.

horde/lib/Test.php
horde/templates/test/header.inc
horde/templates/test/php_version.inc
horde/templates/test/version.inc
horde/test.php
imp/lib/Test.php [new file with mode: 0644]
imp/templates/test/mailserver.inc [new file with mode: 0644]
imp/test.php [deleted file]

index 4dd778e..3e65985 100644 (file)
@@ -1,22 +1,4 @@
 <?php
-
-/**
- * Include the main Horde library, since we require it for this package.
- */
-require_once dirname(__FILE__) . '/core.php';
-
-/**
- * Set the path to the templates needed for testing output.
- */
-define('TEST_TEMPLATES', HORDE_BASE . '/templates/test/');
-
-/* If gettext is not loaded, define a dummy _() function so that
- * including any file with gettext strings won't cause a fatal error,
- * causing test.php to return a blank page. */
-if (!function_exists('_')) {
-    function _($s) { return $s; }
-}
-
 /**
  * The Horde_Test:: class provides functions used in the test scripts
  * used in the various applications (test.php).
@@ -32,51 +14,316 @@ if (!function_exists('_')) {
  * @author  Michael Slusarz <slusarz@horde.org>
  * @package Horde_Test
  */
-class Horde_Test {
 
+/* If gettext is not loaded, define a dummy _() function so that
+ * including any file with gettext strings won't cause a fatal error,
+ * causing test.php to return a blank page. */
+if (!function_exists('_')) {
+    function _($s) { return $s; }
+}
+
+class Horde_Test
+{
     /**
-     * Array that holds the list of Horde applications.
-     * (Loaded from config/registry.php)
+     * The PHP version of the system.
      *
      * @var array
      */
-    var $applications = array();
+    protected $_phpver;
 
     /**
-     * Cached results of getApplications().
+     * Supported versions of PHP.
      *
      * @var array
      */
-    var $_appoutput = array();
+    protected $_supported = array(
+        '5.2', '5.3'
+    );
 
     /**
-     * The PHP version of the system.
+     * The module list
+     * <pre>
+     * KEY:   module name
+     * VALUE: Either the description or an array with the following entries:
+     *        'descrip' - (string) Module description
+     *        'error' - (string) Error message
+     *        'fatal' - (boolean) Is missing module fatal?
+     *        'phpver' - (string) The PHP version above which to do the test
+     * </pre>
      *
      * @var array
      */
-    var $_phpver;
+    protected $_moduleList = array(
+        'ctype' => array(
+            'descrip' => 'Ctype Support',
+            'error' => 'The ctype functions are required by the help system, the weather portal blocks, and a few Horde applications.'
+        ),
+        'dom' => array(
+            'descrip' => 'DOM XML Support',
+            'error' => 'DOM support is required for the configuration frontend and Kolab support.'
+        ),
+        'fileinfo' => array(
+            'descrip' => 'MIME Magic Support (fileinfo)',
+            'error' => 'The fileinfo PECL module is used to provide MIME Magic scanning on unknown data. See horde/docs/INSTALL for information on how to install PECL extensions.'
+        ),
+        'ftp' => array(
+            'descrip' => 'FTP Support',
+            'error' => 'FTP support is only required if you want to authenticate against an FTP server, upload your configuration files with FTP, or use an FTP server for file storage.'
+        ),
+        'gd' => array(
+            'descrip' => 'GD Support',
+            'error' => 'Horde will use the GD extension to perform manipulations on image data. You can also use the ImageMagick software to do these manipulations instead.'
+        ),
+        'gettext' => array(
+            'descrip' => 'Gettext Support',
+            'error' => 'Horde will not run without gettext support. Compile PHP with <code>--with-gettext</code> before continuing.',
+            'fatal' => true
+        ),
+        'geoip' => array(
+            'descrip' => 'GeoIP Support (PECL extension)',
+            'error' => 'Horde can optionally use the GeoIP extension to provide faster country name lookups.'
+        ),
+        'hash' => array(
+            'descrip' => 'Hash Support',
+            'error' => 'Horde will not run without the hash extension. Don\'t compile PHP with <code>--disable-all/--disable-hash</code>, or enable the hash extension individually before continuing.',
+            'fatal' => true
+        ),
+        'iconv' => array(
+            'descrip' => 'Iconv Support',
+            'error' => 'If you want to take full advantage of Horde\'s localization features and character set support, you will need the iconv extension.'
+        ),
+        'iconv_libiconv' => array(
+            'descrip' => 'GNU Iconv Support',
+            'error' => 'For best results make sure the iconv extension is linked against GNU libiconv.',
+            'function' => '_checkIconvImplementation'
+        ),
+        'idn' => array(
+            'descrip' => 'Internationalized Domain Names Support (PECL extension)',
+            'error' => 'Horde requires the idn module to handle Internationalized Domain Names.'
+        ),
+        'imagick' => array(
+            'descrip' => 'Imagick Library',
+            'error' => 'Horde can make use of the Imagick Library, if it is installed on your system.  It is highly recommended to use either ImageMagick\'s convert utility or the Imagick php library for faster results.'
+        ),
+        'json' => array(
+            'descrip' => 'JSON Support',
+            'error' => 'Horde will not run without the json extension. Don\'t compile PHP with <code>--disable-all/--disable-json</code>, or enable the json extension individually before continuing.',
+            'fatal' => true
+        ),
+        'ldap' => array(
+            'descrip' => 'LDAP Support',
+            'error' => 'LDAP support is only required if you want to use an LDAP server for anything like authentication, address books, or preference storage.'
+        ),
+        'lzf' => array(
+            'descrip' => 'LZF Compression Support (PECL extension)',
+            'error' => 'If the lzf PECL module is available, Horde can compress some cached data in your session to make your session size smaller.'
+        ),
+        'mbstring' => array(
+            'descrip' => 'Mbstring Support',
+            'error' => 'If you want to take full advantage of Horde\'s localization features and character set support, you will need the mbstring extension.'
+        ),
+        'mcrypt' => array(
+            'descrip' => 'Mcrypt Support',
+            'error' => 'Mcrypt is a general-purpose cryptography library which is broader and significantly more efficient (FASTER!) than PHP\'s own cryptographic code and will provider faster logins.'
+        ),
+        'memcache' => array(
+            'descrip' => 'memcached Support (memcache) (PECL extension)',
+            'error' => 'The memcache PECL module is only needed if you are using a memcached server for caching or sessions. See horde/docs/INSTALL for information on how to install PECL/PHP extensions.'
+        ),
+        'mysql' => array(
+            'descrip' => 'MySQL Support',
+            'error' => 'The MySQL extension is only required if you want to use a MySQL database server for data storage.'
+        ),
+        'openssl' => array(
+            'descrip' => 'OpenSSL Support',
+            'error' => 'The OpenSSL extension is required for any kind of S/MIME support.'
+        ),
+        'pcre' => array(
+            'descrip' => 'PCRE Support',
+            'error' => 'Horde will not run without the pcre extension. Don\'t compile PHP with <code>--disable-all/--without-pcre-regex</code>, or enable the pcre extension individually before continuing.',
+            'fatal' => true
+        ),
+        'pgsql' => array(
+            'descrip' => 'PostgreSQL Support',
+            'error' => 'The PostgreSQL extension is only required if you want to use a PostgreSQL database server for data storage.'
+        ),
+        'session' => array(
+            'descrip' => 'Session Support',
+            'fatal' => true
+        ),
+        'tidy' => array(
+            'descrip' => 'Tidy support',
+            'error' => 'The tidy PHP extension is used to sanitize HTML data.'
+        ),
+        'xml' => array(
+            'descrip' => 'XML Support',
+            'error' => 'XML support is required for the help system.'
+        ),
+        'zlib' => array(
+            'descrip' => 'Zlib Support',
+            'error' => 'The zlib module is highly recommended for use with Horde.  It allows page compression and handling of ZIP and GZ data. Compile PHP with <code>--with-zlib</code> to activate.'
+        )
+    );
 
     /**
-     * Supported versions of PHP.
+     * PHP settings list.
+     * <pre>
+     * KEY:   setting name
+     * VALUE: An array with the following entries:
+     *        'error' - (string) Error Message
+     *        'setting' - (mixed) Either a boolean (whether setting should be
+     *                    on or off) or 'value', which will simply output the
+     *                    value of the setting.
+     * </pre>
      *
      * @var array
      */
-    var $_supported = array(
-        '5.2', '5.3'
+    protected $_settingsList = array(
+        'magic_quotes_runtime' => array(
+            'setting' => false,
+            'error' => 'magic_quotes_runtime may cause problems with database inserts, etc. Turn it off.'
+        ),
+        'memory_limit' => array(
+            'setting' => 'value',
+            'error' => 'If PHP\'s internal memory limit is not set high enough Horde will not be able to handle large data items. You should set the value of memory_limit in php.ini to a sufficiently high value - at least 64M is recommended.'
+        ),
+        'register_globals' => array(
+            'setting' => false,
+            'error' => 'Register globals has been deprecated in PHP 5. Horde will fatally exit if it is set. Turn it off.'
+        ),
+        'safe_mode' => array(
+            'setting' => false,
+            'error' => 'If safe_mode is enabled, Horde cannot set enviroment variables, which means Horde will be unable to translate the user interface into different languages.'
+        ),
+        'session.auto_start' => array(
+            'setting' => false,
+            'error' => 'Horde won\'t work with automatically started sessions, because it explicitly creates new session when necessary to protect against session fixations.'
+        ),
+        'session.gc_divisor' => array(
+            'setting' => 'value',
+            'error' => 'PHP automatically garbage collects old session information, as long as this setting (and session.gc_probability) are set to non-zero. It is recommended that this value be "10000" or higher (see docs/INSTALL).'
+        ),
+        'session.gc_probability' => array(
+            'setting' => 'value',
+            'error' => 'PHP automatically garbage collects old session information, as long as this setting (and session.gc_divisor) are set to non-zero. It is recommended that this value be "1".'
+        ),
+        'session.use_trans_sid' => array(
+            'setting' => false,
+            'error' => 'Horde will work with session.use_trans_sid turned on, but you may see double session-ids in your URLs, and if the session name in php.ini differs from the session name configured in Horde, you may get two session ids and see other odd behavior. The URL-rewriting that use_trans_sid does also tends to break XHTML compliance. In short, you should really disable this.'
+        ),
+        'zend_accelerator.compress_all' => array(
+            'setting' => false,
+            'error' => 'You should not enable output compression unconditionally because some browsers and scripts don\'t work well with output compression. Enable compression in Horde\'s configuration instead, so that we have full control over the conditions where to enable and disable it.'
+        ),
+        'zlib.output_compression' => array(
+            'setting' => false,
+            'error' => 'You should not enable output compression unconditionally because some browsers and scripts don\'t work well with output compression. Enable compression in Horde\'s configuration instead, so that we have full control over the conditions where to enable and disable it.'
+        )
+    );
+
+    /**
+     * PEAR modules list.
+     * <pre>
+     * KEY:   PEAR class name
+     * VALUE: An array with the following entries:
+     *        'depends' - (?) This module depends on another module.
+     *        'error' - (string) Error message.
+     *        'function' - (string) Reference to function to run if module is
+     *                     found.
+     *        'path' - (string) The path to the PEAR module. Only needed if
+     *                 KEY is not autoloadable.
+     *        'required' - (boolean) Is this PEAR module required?
+     * </pre>
+     *
+     * @var array
+     */
+    protected $_pearList = array(
+        'Auth_SASL' => array(
+            'error' => 'Horde will work without the Auth_SASL class, but if you use Access Control Lists in IMP you should be aware that without this class passwords will be sent to the IMAP server in plain text when retrieving ACLs.'
+        ),
+        'Cache' => array(
+            'error' => 'Cache is used by the Services_Weather module on the weather applet/block on the portal page.'
+        ),
+        'Date' => array(
+            'path' => 'Date/Calc.php',
+            'error' => 'Horde requires the Date_Calc class for Kronolith to calculate dates.'
+        ),
+        'DB' => array(
+            'error' => 'You will need DB if you are using SQL.',
+            'function' => '_checkPearDbVersion'
+        ),
+        'HTTP_Request' => array(
+            'error' => 'Parts of Horde (Jonah, the XML-RPC client/server) use the HTTP_Request library to retrieve URLs and do other HTTP requests.'
+        ),
+        'HTTP_WebDAV_Server' => array(
+            'error' => 'The HTTP_WebDAV_Server is required if you want to use the WebDAV interface of Horde, e.g. to access calendars or tasklists with external clients.'
+        ),
+        'Log' => array(
+            'error' => 'Make sure you are using a version of PEAR which includes the Log classes, or that you have installed the Log package seperately. See the INSTALL file for instructions on installing Log.',
+            'function' => '_checkPearLogVersion',
+            'required' => true
+        ),
+        'Mail' => array(
+            'path' => 'Mail/RFC822.php',
+            'error' => 'You do not have the Mail package installed on your system. See the INSTALL file for instructions on how to install the package.'
+        ),
+        'MDB2' => array(
+            'error' => 'You will need MDB2 if you are using the SQL driver for Shares.',
+        ),
+        'Net_DNS' => array(
+            'error' => 'Net_DNS can speed up hostname lookups against broken DNS servers.'
+        ),
+        'Net_SMTP' => array(
+            'error' => 'Make sure you are using the Net_SMTP module if you want "smtp" to work as a mailer option.'
+        ),
+        'Net_Socket' => array(
+            'error' => 'Make sure you are using a version of PEAR which includes the Net_Socket class, or that you have installed the Net_Socket package seperately. See the INSTALL file for instructions on installing Net_Socket.'
+        ),
+        'Services_Weather' => array(
+            'error' => 'Services_Weather is used by the weather applet/block on the portal page.'
+        ),
+        'XML_Serializer' => array(
+            'error' => 'XML_Serializer is used by the Services_Weather module on the weather applet/block on the portal page.'
+        )
     );
 
     /**
+     * Required configuration files.
+     * <pre>
+     * KEY:   file path
+     * VALUE: The error message to use (null to use default message)
+     * </pre>
+     *
+     * @var array
+     */
+    protected $_fileList = array(
+        'config/conf.php' => null,
+        'config/mime_drivers.php' => null,
+        'config/nls.php' => null,
+        'config/prefs.php' => null,
+        'config/registry.php' => null
+    );
+
+    /**
+     * Inter-Horde application dependencies.
+     * <pre>
+     * KEY:   app name
+     * VALUE: An array with the following entries:
+     *        'error' - (string) Error message.
+     *        'version' - (string) Minimum version required of the app.
+     * </pre>
+     *
+     * @var array
+     */
+    protected $_appList = array();
+
+    /**
      * Constructor.
      */
-    function Horde_Test()
+    public function __construct()
     {
-        if (file_exists(HORDE_BASE . '/config/registry.php')) {
-            include HORDE_BASE . '/config/registry.php';
-            ksort($this->applications);
-        }
-
         /* Store the PHP version information. */
-        $this->_phpver = $this->splitPHPVersion(PHP_VERSION);
+        $this->_phpver = $this->_splitPhpVersion(PHP_VERSION);
 
         /* We want to be as verbose as possible here. */
         error_reporting(E_ALL);
@@ -94,7 +341,7 @@ class Horde_Test {
      * @param array  The parsed string.
      *               Keys: 'major', 'minor', 'subminor', 'class'
      */
-    function splitPHPVersion($version)
+    protected function _splitPhpVersion($version)
     {
         /* First pick off major version, and lower-case the rest. */
         if ((strlen($version) >= 3) && ($version[1] == '.')) {
@@ -125,7 +372,7 @@ class Horde_Test {
         $phpver['minor'] = substr($version, 0, $s);
         if ((strlen($version) > $s) &&
             (($version[$s] == '.') || ($version[$s] == '-'))) {
-            $s++;
+            ++$s;
         }
         $phpver['subminor'] = substr($version, $s);
         if (($phpver['subminor'] == 'cvs') ||
@@ -146,24 +393,13 @@ class Horde_Test {
     /**
      * Check the list of PHP modules.
      *
-     * @param array $modlist  The module list.
-     * <pre>
-     * KEY:   module name
-     * VALUE: Either the description or an array with the following entries:
-     *        'descrip'  --  Module Description
-     *        'error'    --  Error Message
-     *        'fatal'    --  Is missing module fatal?
-     *        'phpver'   --  The PHP version above which to do the test
-     * </pre>
-     *
      * @return string  The HTML output.
      */
-    function phpModuleCheck($modlist)
+    public function phpModuleCheck()
     {
         $output = '';
-        $output_array = array();
 
-        foreach ($modlist as $key => $val) {
+        foreach ($this->_moduleList as $key => $val) {
             $error_msg = $mod_test = $status_out = $fatal = null;
             $test_function = null;
             $entry = array();
@@ -188,7 +424,7 @@ class Horde_Test {
 
             if (is_null($status_out)) {
                 if (!is_null($test_function)) {
-                    $mod_test = call_user_func($test_function);
+                    $mod_test = call_user_func(array($this, $test_function));
                 } else {
                     $mod_test = extension_loaded($key);
                 }
@@ -218,25 +454,32 @@ class Horde_Test {
     }
 
     /**
+     * Additional check for iconv module implementation.
+     *
+     * @return string  Returns error string on error.
+     */
+    protected function _checkIconvImplementation()
+    {
+        return extension_loaded('iconv') &&
+               in_array(ICONV_IMPL, array('libiconv', 'glibc'));
+    }
+
+    /**
      * Checks the list of PHP settings.
      *
-     * @param array $modlist  The settings list.
-     * <code>
-     * KEY:   setting name
-     * VALUE: An array with the following entries:
-     *        'error'    --  Error Message
-     *        'setting'  --  Either a boolean (whether setting should be on or
-     *                       off) or 'value', which will simply output the
-     *                       value of the setting.
-     * </code>
+     * @params array $settings  The list of settings to check.
      *
      * @return string  The HTML output.
      */
-    function phpSettingCheck($settings_list)
+    public function phpSettingCheck($settings = null)
     {
         $output = '';
 
-        foreach ($settings_list as $key => $val) {
+        if (is_null($settings)) {
+            $settings = $this->_settingsList;
+        }
+
+        foreach ($settings as $key => $val) {
             $entry = array();
             if (is_bool($val['setting'])) {
                 $result = (ini_get($key) == $val['setting']);
@@ -262,20 +505,9 @@ class Horde_Test {
     /**
      * Check the list of PEAR modules.
      *
-     * @param array $pear_list  The PEAR module list.
-     * <pre>
-     * KEY:   PEAR class name
-     * VALUE: An array with the following entries:
-     *        'depends'   --  This module depends on another module
-     *        'error'     --  Error Message
-     *        'function'  --  Reference to function to run if module is found
-     *        'path'      --  The path to the PEAR module
-     *        'required'  --  Is this PEAR module required? (boolean)
-     * </pre>
-     *
      * @return string  The HTML output.
      */
-    function PEARModuleCheck($pear_list)
+    public function pearModuleCheck()
     {
         $output = '';
 
@@ -286,23 +518,20 @@ class Horde_Test {
         $output .= $this->_outputLine(array("<strong>PEAR Search Path (PHP's include_path)</strong>", '&nbsp;<tt>' . ini_get('include_path') . '</tt>'));
 
         /* Check for PEAR in general. */
-        {
-            $entry = array();
-            $entry[] = 'PEAR';
-            @include_once 'PEAR.php';
-            $entry[] = $this->_status(!isset($php_errormsg));
-            if (isset($php_errormsg)) {
-                $entry[] = 'Check your PHP include_path setting to make sure it has the PEAR library directory.';
-                $output .= $this->_outputLine($entry);
-                ini_restore('track_errors');
-                return $output;
-            }
+        $entry = array();
+        $entry[] = 'PEAR';
+        $entry[] = $this->_status(!isset($php_errormsg));
+        if (isset($php_errormsg)) {
+            $entry[] = 'Check your PHP include_path setting to make sure it has the PEAR library directory.';
             $output .= $this->_outputLine($entry);
+            ini_restore('track_errors');
+            return $output;
         }
+        $output .= $this->_outputLine($entry);
 
         /* Check for a recent PEAR version. */
         $entry = array();
-        $newpear = $this->isRecentPEAR();
+        $newpear = $this->_isRecentPear();
         $entry[] = 'Recent PEAR';
         $entry[] = $this->_status($newpear);
         if (!$newpear) {
@@ -312,19 +541,21 @@ class Horde_Test {
 
         /* Go through module list. */
         $succeeded = array();
-        foreach ($pear_list as $key => $val) {
+        foreach ($this->_pearList as $key => $val) {
             $entry = array();
 
             /* If this module depends on another module that we
              * haven't succesfully found, fail the test. */
             if (!empty($val['depends']) && empty($succeeded[$val['depends']])) {
                 $result = false;
+            } elseif (empty($val['path'])) {
+                $result = class_exists($key);
             } else {
                 $result = @include_once $val['path'];
             }
             $error_msg = $val['error'];
             if ($result && isset($val['function'])) {
-                $func_output = call_user_func($val['function']);
+                $func_output = call_user_func(array($this, $val['function']));
                 if ($func_output) {
                     $result = false;
                     $error_msg = $func_output;
@@ -355,23 +586,42 @@ class Horde_Test {
     }
 
     /**
-     * Check the list of required files
+     * Additional check for PEAR Log module for its version.
      *
-     * @param array $file_list  The file list.
-     * <pre>
-     * KEY:   file path
-     * VALUE: The error message to use (null to use default message)
-     * </pre>
+     * @return string  Returns error string on error.
+     */
+    protected function _checkPearLogVersion()
+    {
+        if (!defined('PEAR_LOG_INFO')) {
+            return 'Your version of Log is not recent enough.';
+        }
+    }
+
+    /**
+     * Additional check for PEAR DB module for its version.
+     *
+     * @return string  Returns error string on error.
+     */
+    protected function _checkPearDbVersion()
+    {
+        if (!defined('DB_PORTABILITY_LOWERCASE')) {
+            return 'Your version of DB is not recent enough.';
+        }
+    }
+
+    /**
+     * Check the list of required files
      *
      * @return string  The HTML output.
      */
-    function requiredFileCheck($file_list)
+    public function requiredFileCheck()
     {
         $output = '';
+        $filedir = $GLOBALS['registry']->get('fileroot');
 
-        foreach ($file_list as $key => $val) {
+        foreach ($this->_fileList as $key => $val) {
             $entry = array();
-            $result = file_exists('./' . $key);
+            $result = file_exists($filedir . '/' . $key);
 
             $entry[] = $key;
             $entry[] = $this->_status($result);
@@ -391,156 +641,34 @@ class Horde_Test {
     }
 
     /**
-     * Displays an error screen with a list of all configuration files that
-     * are missing, together with a description what they do and how they are
-     * created. If a file can be automatically created from the defaults, then
-     * we do that instead and don't display an error.
-     *
-     * @param string $app        The application name
-     * @param string $appBase    The path to the application
-     * @param array  $files      An array with the "standard" configuration
-     *                           files that should be checked. Currently
-     *                           supported:
-     *                           - conf.php
-     *                           - prefs.php
-     *                           - mime_drivers.php
-     * @param array $additional  An associative array containing more files (as
-     *                           keys) and error message (as values) if they
-     *                           don't exist.
-     */
-    function configFilesMissing($app, $appBase, $files, $additional = array())
-    {
-        /* Try to load a basic framework if we're testing an app other than
-         * the Horde base files. */
-        if ($app != 'Horde') {
-            $GLOBALS['registry'] = Horde_Registry::singleton();
-            $GLOBALS['registry']->pushApp('horde', array('check_perms' => false));
-        }
-
-        if (!is_array($files)) {
-            $files = array($files);
-        }
-        $files = array_merge($files, array_keys($additional));
-
-        /* Try to auto-create missing .dist files. */
-        $indices = array_keys($files);
-        foreach ($indices as $index) {
-            if (is_readable($appBase . '/config/' . $files[$index])) {
-                unset($files[$index]);
-            } else {
-                if (file_exists($appBase . '/config/' . $files[$index] . '.dist') &&
-                    @copy($appBase . '/config/' . $files[$index] . '.dist', $appBase . '/config/' . $files[$index])) {
-                    unset($files[$index]);
-                }
-            }
-        }
-
-        /* Return if we have no missing files left. */
-        if (!count($files)) {
-            return;
-        }
-
-        $descriptions = array_merge(array(
-            'conf.php' => sprintf('This is the main %s configuration file. ' .
-                                  'It contains paths and options for the %s ' .
-                                  'scripts. You need to login as an ' .
-                                  'administrator and create the file with ' .
-                                  'the web frontend under "Administration => ' .
-                                  'Setup".',
-                                  $app, $app, $appBase . '/config'),
-            'prefs.php' => sprintf('This file controls the default preferences ' .
-                                   'for %s, and also controls which preferences ' .
-                                   'users can alter.', $app),
-            'mime_drivers.php' => sprintf('This file controls local MIME ' .
-                                          'drivers for %s, specifically what ' .
-                                          'kinds of files are viewable and/or ' .
-                                          'downloadable.', $app),
-            'backends.php' => sprintf('This file controls what backends are ' .
-                                      'available from %s.', $app),
-            'sources.php' => sprintf('This file defines the list of available ' .
-                                     'sources for %s.', $app)
-        ), $additional);
-
-        /* If we know the user is an admin, give them a direct link to
-         * generate conf.php. In the future, should we try generating
-         * a basic conf.php automagically here? */
-        if (Horde_Auth::isAdmin()) {
-            $setup_url = Horde::link(Horde::url($GLOBALS['registry']->get('webroot', 'horde') .
-                                                '/admin/setup/config.php?app=' . Horde_String::lower($app))) .
-                'Configuration Web Interface' . '</a>';
-            $descriptions['conf.php'] =
-                sprintf('This is the main %s configuration file. ' .
-                        'Generate it by going to the %s.',
-                        $app, $setup_url);
-        }
-
-        $title = sprintf('%s is not properly configured', $app);
-        $header = sprintf('Some of %s\'s configuration files are missing or unreadable', $app);
-        $footer = sprintf('Create these files from their .dist versions in %s and change them according to your needs.', $appBase . '/config');
-
-        echo <<< HEADER
-<html>
-<head><title>$title</title></head>
-<body style="background-color: white; color: black;">
-<h1>$header</h1>
-HEADER;
-
-        foreach ($files as $file) {
-            if (empty($descriptions[$file])) {
-                continue;
-            }
-            $description = $descriptions[$file];
-            echo <<< FILE
-    <h3>$file</h3><p>$description</p>
-FILE;
-        }
-
-        echo <<< FOOTER
-
-<h2>$footer</h2>
-</body>
-</html>
-FOOTER;
-        exit;
-    }
-
-    /**
      * Check the list of required Horde applications.
      *
-     * @param array $app_list  The application list.
-     * <pre>
-     * KEY:   application name
-     * VALUE: An array with the following entries:
-     *        'error'    --  Error Message
-     *        'version'  --  The minimum version required
-     * </pre>
-     *
      * @return string  The HTML output.
      */
-    function requiredAppCheck($app_list)
+    public function requiredAppCheck()
     {
         $output = '';
 
-        $apps = $this->applicationList();
+        $horde_apps = $GLOBALS['registry']->listApps(null, true);
 
-        foreach ($app_list as $key => $val) {
+        foreach ($this->_appList as $key => $val) {
             $entry = array();
             $entry[] = $key;
 
-            if (!isset($apps[$key])) {
+            if (!isset($horde_apps[$key])) {
                 $entry[] = $this->_status(false, false);
                 $entry[] = $val['error'];
                 $entry[] = 1;
             } else {
-                /* Strip '-cvs', '-git', and H3|H4 (ver) from version string. */
-                $appver = str_replace(array('-cvs', '-git'), array('', ''), $apps[$key]->version);
-                $appver = preg_replace('/(H3|H4) \((.*)\)/', '$2', $appver);
+                /* Strip '-git', and H# (ver) from version string. */
+                $origver = $GLOBALS['registry']->getVersion($key);
+                $appver = preg_replace('/(H\d) \((.*)\)/', '$2', str_replace('-git', '', $origver));
                 if (version_compare($val['version'], $appver) === 1) {
-                    $entry[] = $this->_status(false, false) . ' (Have version: ' . $apps[$key]->version . '; Need version: ' . $val['version'] . ')';
+                    $entry[] = $this->_status(false, false) . ' (Have version: ' . $origver . '; Need version: ' . $val['version'] . ')';
                     $entry[] = $val['error'];
                     $entry[] = 1;
                 } else {
-                    $entry[] = $this->_status(true) . ' (Version: ' . $apps[$key]->version . ')';
+                    $entry[] = $this->_status(true) . ' (Version: ' . $origver . ')';
                 }
             }
             $output .= $this->_outputLine($entry);
@@ -554,9 +682,8 @@ FOOTER;
      *
      * @param boolean  True if a recent version of PEAR.
      */
-    function isRecentPEAR()
+    protected function _isRecentPear()
     {
-        @include_once 'PEAR.php';
         $pear_methods = get_class_methods('PEAR');
         return (is_array($pear_methods) &&
                 (in_array('registershutdownfunc', $pear_methods) ||
@@ -568,7 +695,7 @@ FOOTER;
      *
      * @return object stdClass  TODO
      */
-    function getPhpVersionInformation()
+    public function getPhpVersionInformation()
     {
         $output = new stdClass;
         $url = urlencode($_SERVER['PHP_SELF']);
@@ -588,7 +715,7 @@ FOOTER;
         $output->class = $this->_phpver['class'];
 
         $output->status_color = 'red';
-        if ($output->major < '4.3') {
+        if ($output->major < '5.2') {
             $output->status = 'This version of PHP is not supported. You need to upgrade to a more recent version.';
             $vers_check = false;
         } elseif (in_array($output->major, $this->_supported)) {
@@ -600,72 +727,34 @@ FOOTER;
         }
 
         if (!$vers_check) {
-            $output->version_check = 'Horde requires PHP 4.3.0 or greater.';
+            $output->version_check = 'Horde requires PHP 5.2.0 or greater.';
         }
 
         return $output;
     }
 
     /**
-     * Get the application list.
-     *
-     * @return array  List of stdClass objects.
-     *                KEY: application name
-     *                ELEMENT 'version': Version of application
-     *                ELEMENT 'test': The location of the test script (if any)
-     */
-    function applicationList()
-    {
-        if (!empty($this->_appoutput)) {
-            return $this->_appoutput;
-        }
-
-        foreach ($this->applications as $mod => $det) {
-            if (($det['status'] != 'heading') &&
-                ($det['status'] != 'block')) {
-                $classname = $mod . '_Application';
-                if ((@include_once $det['fileroot'] . '/lib/Application.php') &&
-                    class_exists($classname)) {
-                    $api = new $classname;
-                    $this->_appoutput[$mod] = new stdClass;
-                    $this->_appoutput[$mod]->version = $api->version;
-                    if (($mod != 'horde') &&
-                        is_readable($det['fileroot'] . '/test.php')) {
-                        $this->_appoutput[$mod]->test = $det['webroot'] . '/test.php';
-                    }
-                }
-            }
-        }
-
-        return $this->_appoutput;
-    }
-
-    /**
      * Output the results of a status check.
      *
-     * @access private
-     *
      * @param boolean $bool      The result of the status check.
      * @param boolean $required  Whether the checked item is required.
      *
      * @return string  The HTML of the result of the status check.
      */
-    function _status($bool, $required = true)
+    protected function _status($bool, $required = true)
     {
         if ($bool) {
             return '<strong style="color:green">Yes</strong>';
         } elseif ($required) {
             return '<strong style="color:red">No</strong>';
-        } else {
-            return '<strong style="color:orange">No</strong>';
         }
+
+        return '<strong style="color:orange">No</strong>';
     }
 
     /**
      * Internal output function.
      *
-     * @access private
-     *
      * @param array $entry  Array with the following values:
      * <pre>
      * 1st value: Header
@@ -676,16 +765,50 @@ FOOTER;
      *
      * @return string  HTML output.
      */
-    function _outputLine($entry)
+    protected function _outputLine($entry)
     {
         $output = '<li>' . array_shift($entry) . ': ' . array_shift($entry);
         if (!empty($entry)) {
             $msg = array_shift($entry);
             $output .= '<br /><strong style="color:' . (empty($entry) || !array_shift($entry) ? 'red' : 'orange') . '">' . $msg . "</strong>\n";
         }
-        $output .= '</li>' . "\n";
 
-        return $output;
+        return $output . "</li>\n";
+    }
+
+    /**
+     * Any application specific tests that need to be done.
+     *
+     * @return string  HTML output.
+     */
+    public function appTests()
+    {
+        /* File upload information. */
+        $upload_check = $this->phpSettingCheck(array(
+            'file_uploads' => array(
+                'error' => 'file_uploads must be enabled for some features like sending emails with IMP.',
+                'setting' => true
+            )
+        ));
+        $upload_tmp_dir = ($dir = ini_get('upload_tmp_dir'))
+            ? '<li>upload_tmp_dir: <strong style="color:"' . (is_writable($dir) ? 'green' : 'red') . '">' . $dir . '</strong></li>'
+            : '';
+
+        $ret = '<h1>File Uploads</h1><ul>' .
+            $upload_check .
+            $upload_tmp_dir .
+            '<li>upload_max_filesize: ' . ini_get('upload_max_filesize') . '</li>'.
+            '<li>post_max_size: ' . ini_get('post_max_size') . '<br />' .
+            'This value should be several times the expect largest upload size (notwithstanding any upload limits present in an application). Any upload that exceeds this size will cause any state information sent along with the uploaded data to be lost. This is a PHP limitation and can not be worked around.'.
+            '</li></ul>';
+
+        /* Determine if 'static' is writable by the web user. */
+        $ret .= '<h1>Local File Permissions</h1><ul>' .
+            '<li>Is <tt>' . htmlspecialchars(HORDE_BASE) . '/static</tt> writable by the web server user? ';
+        $ret .= is_writable(HORDE_BASE . '/static')
+            ? 'Yes'
+            : "<strong style=\"color:red\">No</strong><br /><strong style=\"color:orange\">If caching javascript and CSS files by storing them in static files (HIGHLY RECOMMENDED), this directory must be writable as the user the web server runs as.</strong>";
+        return $ret . '</li></ul>';
     }
 
 }
index 2180687..26f502c 100644 (file)
@@ -1,7 +1,7 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
 <html>
 <head>
-<title><?php echo $module ?>: System Capabilities Test</title>
+<title><?php echo $app_name ?>: System Capabilities Test</title>
 <style type="text/css">
 body { font-family: Geneva,Arial,Helvetica,sans-serif; font-size: 90% }
 td { font-family: Geneva,Arial,Helvetica,sans-serif }h1 { font-size: 110%; color: black; font-family: Verdana,Geneva,Arial,Helvetica,sans-serif; }
index 2a93eef..6c94f9b 100644 (file)
@@ -1,23 +1,21 @@
 <h1>PHP Version</h1>
 <ul>
-<?php if (!empty($test_app) && Horde_Util::nonInputVar('test_app') == 'horde'): ?>
-    <li><a href="<?php echo $php_info->phpinfo ?>">View phpinfo() screen</a></li>
-    <li><a href="<?php echo $php_info->extensions ?>">View loaded extensions</a></li>
-<?php endif; ?>
-    <li>PHP Version: <?php echo $php_info->version ?></li>
-    <li>PHP Major Version: <?php echo $php_info->major ?></li>
+ <li><a href="<?php echo $php_info->phpinfo ?>">View phpinfo() screen</a></li>
+ <li><a href="<?php echo $php_info->extensions ?>">View loaded extensions</a></li>
+ <li>PHP Version: <?php echo $php_info->version ?></li>
+ <li>PHP Major Version: <?php echo $php_info->major ?></li>
 <?php if (isset($php_info->minor)): ?>
   <li>PHP Minor Version: <?php echo $php_info->minor ?></li>
+ <li>PHP Minor Version: <?php echo $php_info->minor ?></li>
 <?php endif; ?>
 <?php if (isset($php_info->subminor)): ?>
   <li>PHP Subminor Version: <?php echo $php_info->subminor ?></li>
+ <li>PHP Subminor Version: <?php echo $php_info->subminor ?></li>
 <?php endif; ?>
   <li>PHP Version Classification: <?php echo $php_info->class ?></li>
   <li style="color:<?php echo $php_info->status_color ?>"><strong><?php echo $php_info->status ?></strong></li>
+ <li>PHP Version Classification: <?php echo $php_info->class ?></li>
+ <li style="color:<?php echo $php_info->status_color ?>"><strong><?php echo $php_info->status ?></strong></li>
 <?php if (isset($php_info->version_check)): ?>
   <li><?php echo $php_info->version_check ?></li>
+ <li><?php echo $php_info->version_check ?></li>
 <?php endif; ?>
 <?php if (isset($php_info->insecure)): ?>
   <li style="color:orange"><strong><?php echo $php_info->insecure ?><strong></li>
+ <li style="color:orange"><strong><?php echo $php_info->insecure ?><strong></li>
 <?php endif; ?>
 </ul>
index ae9f9be..59d7461 100644 (file)
@@ -1,4 +1,4 @@
-<h1><?php echo $module ?> Version</h1>
+<h1><?php echo $app_name ?> Version</h1>
 <ul>
   <li><?php echo $module ?>: <?php echo $module_version ?></li>
<li><?php echo $app_name ?>: <?php echo $app_version ?></li>
 </ul>
index 07dcb04..eb9b6e2 100644 (file)
@@ -1,5 +1,14 @@
 <?php
 /**
+ * Horde test script.
+ *
+ * Parameters:
+ * -----------
+ * 'app' - (string) The app to test.
+ *         DEFAULT: horde
+ * 'mode' - (string) TODO
+ * 'url' - (string) TODO
+ *
  * Copyright 1999-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  *
  * @author Brent J. Nordquist <bjn@horde.org>
  * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Michael Slusarz <slusarz@horde.org>
  */
 
-/* Register a session. */
-session_start();
-if (!isset($_SESSION['horde_test_count'])) {
-    $_SESSION['horde_test_count'] = 0;
-}
-
-/* Include Horde's core.php file. */
-include_once 'lib/core.php';
+require_once dirname(__FILE__) . '/lib/Application.php';
+$api = new Horde_Application(array('authentication' => 'none'));
 
-/* We should have loaded the String class, from the Horde_Util package, in
- * core.php. If Horde_String:: isn't defined, then we're not finding some critical
- * libraries. */
+/* We should have loaded the String class, from the Horde_Util package. If it
+ * isn't defined, then we're not finding some critical libraries. */
 if (!class_exists('Horde_String')) {
-    echo '<br /><h2 style="color:red">The Horde_Util package was not found. If PHP\'s error_reporting setting is high enough and display_errors is on, there should be error messages printed above that may help you in debugging the problem. If you are simply missing these files, then you need to get the <a href="http://cvs.horde.org/cvs.php/framework">framework</a> module from <a href="http://www.horde.org/source/">Horde CVS</a>, and install the packages in it with the install-packages.php script.</h2>';
+    echo '<br /><h2 style="color:red">Required Horde libraries were not found. If PHP\'s error_reporting setting is high enough and display_errors is on, there should be error messages printed above that may help you in debugging the problem. If you are simply missing these files, then you need to install the framework module.</h2>';
     exit;
 }
 
 /* Initialize the Horde_Test:: class. */
-if (!include_once 'lib/Test.php') {
+if (!class_exists('Horde_Test')) {
     /* Try and provide enough information to debug the missing file. */
-    echo '<br /><h2 style="color:red">Unable to find horde/lib/Test.php. Your Horde installation may be missing critical files, or PHP may not have sufficient permissions to include files. There may be error messages printed above this message that will help you in debugging the problem.</h2>';
+    echo '<br /><h2 style="color:red">Unable to find the Horde_Test library. Your Horde installation may be missing critical files, or PHP may not have sufficient permissions to include files. There may be error messages printed above this message that will help you in debugging the problem.</h2>';
     exit;
 }
 
+/* Load the application. */
+$app = Horde_Util::getFormData('app', 'horde');
+$app_name = $registry->get('name', $app);
+$app_version = $registry->getVersion($app);
+
 /* If we've gotten this far, we should have found enough of Horde to run
  * tests. Create the testing object. */
-$horde_test = new Horde_Test();
-
-/* Horde definitions. */
-$module = 'Horde';
-require_once dirname(__FILE__) . '/lib/Application.php';
-$api = new Horde_Application();
-$module_version = $api->version;
-
-/* PHP module capabilities. */
-$module_list = array(
-    'ctype' => array(
-        'descrip' => 'Ctype Support',
-        'error' => 'The ctype functions are required by the help system, the weather portal blocks, and a few Horde applications.'),
-    (version_compare(PHP_VERSION, '5') < 0 ? 'domxml' : 'dom') => array(
-        'descrip' => 'DOM XML Support',
-        'error' => 'DOM support is required for the configuration frontend and Kolab support.'),
-    'ftp' => array(
-        'descrip' => 'FTP Support',
-        'error' => 'FTP support is only required if you want to authenticate against an FTP server, upload your configuration files with FTP, or use an FTP server for file storage.'),
-    'gd' => array(
-        'descrip' => 'GD Support',
-        'error' => 'Horde will use the GD extension to perform manipulations on image data. You can also use the ImageMagick software to do these manipulations instead.'),
-    'gettext' => array(
-        'descrip' => 'Gettext Support',
-        'error' => 'Horde will not run without gettext support. Compile PHP with <code>--with-gettext</code> before continuing.',
-        'fatal' => true),
-    'geoip' => array(
-        'descrip' => 'GeoIP Support (PECL extension)',
-        'error' => 'Horde can optionally use the GeoIP extension to provide faster country name lookups.'),
-    'hash' => array(
-        'descrip' => 'Hash Support',
-        'error' => 'Horde will not run without the hash extension. Don\'t compile PHP with <code>--disable-all/--disable-hash</code>, or enable the hash extension individually before continuing.',
-        'fatal' => true),
-    'iconv' => array(
-        'descrip' => 'Iconv Support',
-        'error' => 'If you want to take full advantage of Horde\'s localization features and character set support, you will need the iconv extension.'
-    ),
-    'iconv_libiconv' => array(
-        'descrip' => 'GNU Iconv Support',
-        'error' => 'For best results make sure the iconv extension is linked against GNU libiconv.',
-        'function' => '_check_iconv_implementation'),
-    'idn' => array(
-        'descrip' => 'Internationalized Domain Names Support (PECL extension)',
-        'error' => 'Horde requires the idn module to handle Internationalized Domain Names.'),
-    'imagick' => array(
-        'descrip' => 'Imagick Library',
-        'error' => 'Horde can make use of the Imagick Library, if it is installed on your system.  It is highly recommended to use either ImageMagick\'s convert utility or the Imagick php library for faster results.'
-    ),
-    'json' => array(
-        'descrip' => 'JSON Support',
-        'error' => 'Horde will not run without the json extension. Don\'t compile PHP with <code>--disable-all/--disable-json</code>, or enable the json extension individually before continuing.',
-        'fatal' => true),
-    'ldap' => array(
-        'descrip' => 'LDAP Support',
-        'error' => 'LDAP support is only required if you want to use an LDAP server for anything like authentication, address books, or preference storage.'),
-    'lzf' => array(
-        'descrip' => 'LZF Compression Support',
-        'error' => 'If the lzf PECL module is available, Horde can compress some cached data in your session to make your session size smaller.'),
-    'mbstring' => array(
-        'descrip' => 'Mbstring Support',
-        'error' => 'If you want to take full advantage of Horde\'s localization features and character set support, you will need the mbstring extension.'),
-    'pcre' => array(
-        'descrip' => 'PCRE Support',
-        'error' => 'Horde will not run without the pcre extension. Don\'t compile PHP with <code>--disable-all/--without-pcre-regex</code>, or enable the pcre extension individually before continuing.',
-        'fatal' => true),
-    'mcrypt' => array(
-        'descrip' => 'Mcrypt Support',
-        'error' => 'Mcrypt is a general-purpose cryptography library which is broader and significantly more efficient (FASTER!) than PHP\'s own cryptographic code and will provider faster logins.'),
-    'memcache' => array(
-        'descrip' => 'memcached Support (memcache)',
-        'error' => 'The memcache PECL module is only needed if you are using a memcached server for caching or sessions. See horde/docs/INSTALL for information on how to install PECL/PHP extensions.'),
-    'fileinfo' => array(
-        'descrip' => 'MIME Magic Support (fileinfo)',
-        'error' => 'The fileinfo PECL module is used to provide MIME Magic scanning on unknown data. See horde/docs/INSTALL for information on how to install PECL extensions.'),
-    'mysql' => array(
-        'descrip' => 'MySQL Support',
-        'error' => 'The MySQL extension is only required if you want to use a MySQL database server for data storage.'),
-    'openssl' => array(
-        'descrip' => 'OpenSSL Support',
-        'error' => 'The OpenSSL extension is required for any kind of S/MIME support.'),
-    'pgsql' => array(
-        'descrip' => 'PostgreSQL Support',
-        'error' => 'The PostgreSQL extension is only required if you want to use a PostgreSQL database server for data storage.'),
-    'session' => array(
-        'descrip' => 'Session Support',
-        'fatal' => true),
-    'tidy' => array(
-        'descrip' => 'Tidy support',
-        'error' => 'The tidy PHP extension is used to sanitize HTML data.',
-        'fatal' => false),
-    'xml' => array(
-        'descrip' => 'XML Support',
-        'error' => 'XML support is required for the help system.'),
-    'zlib' => array(
-        'descrip' => 'Zlib Support',
-        'error' => 'The zlib module is highly recommended for use with Horde.  It allows page compression and handling of ZIP and GZ data. Compile PHP with <code>--with-zlib</code> to activate.'),
-);
-
-/**
- * Additional check for iconv module implementation.
- */
-function _check_iconv_implementation()
-{
-    return extension_loaded('iconv') && in_array(ICONV_IMPL, array('libiconv', 'glibc'));
+if ($app != 'horde') {
+    $registry->pushApp($app);
 }
-
-/* PHP Settings. */
-$setting_list = array(
-    'magic_quotes_runtime' => array(
-        'setting' => false,
-        'error' => 'magic_quotes_runtime may cause problems with database inserts, etc. Turn it off.'
-    ),
-    'memory_limit' => array(
-        'setting' => 'value',
-        'error' => 'If PHP\'s internal memory limit is not set high enough Horde will not be able to handle large data items. You should set the value of memory_limit in php.ini to a sufficiently high value - at least 64M is recommended.'
-    ),
-    'register_globals' => array(
-        'setting' => false,
-        'error' => 'Register globals has been deprecated in PHP 5. Horde will fatally exit if it is set. Turn it off.'
-    ),
-    'safe_mode' => array(
-        'setting' => false,
-        'error' => 'If safe_mode is enabled, Horde cannot set enviroment variables, which means Horde will be unable to translate the user interface into different languages.'
-    ),
-    'session.auto_start' => array(
-        'setting' => false,
-        'error' => 'Horde won\'t work with automatically started sessions, because it explicitly creates new session when necessary to protect against session fixations.'
-    ),
-    'session.gc_divisor' => array(
-        'setting' => 'value',
-        'error' => 'PHP automatically garbage collects old session information, as long as this setting (and session.gc_probability) are set to non-zero. It is recommended that this value be "10000" or higher (see docs/INSTALL).'
-    ),
-    'session.gc_probability' => array(
-        'setting' => 'value',
-        'error' => 'PHP automatically garbage collects old session information, as long as this setting (and session.gc_divisor) are set to non-zero. It is recommended that this value be "1".'
-    ),
-    'session.use_trans_sid' => array(
-        'setting' => false,
-        'error' => 'Horde will work with session.use_trans_sid turned on, but you may see double session-ids in your URLs, and if the session name in php.ini differs from the session name configured in Horde, you may get two session ids and see other odd behavior. The URL-rewriting that use_trans_sid does also tends to break XHTML compliance. In short, you should really disable this.'
-    ),
-    'zlib.output_compression' => array(
-        'setting' => false,
-        'error' => 'You should not enable output compression unconditionally because some browsers and scripts don\'t work well with output compression. Enable compression in Horde\'s configuration instead, so that we have full control over the conditions where to enable and disable it.'
-    ),
-    'zend_accelerator.compress_all' => array(
-        'setting' => false,
-        'error' => 'You should not enable output compression unconditionally because some browsers and scripts don\'t work well with output compression. Enable compression in Horde\'s configuration instead, so that we have full control over the conditions where to enable and disable it.'
-    ),
-);
-
-/* PEAR */
-$pear_list = array(
-    'Mail' => array(
-        'path' => 'Mail/RFC822.php',
-        'error' => 'You do not have the Mail package installed on your system. See the INSTALL file for instructions on how to install the package.'
-    ),
-    'Log' => array(
-        'path' => 'Log.php',
-        'error' => 'Make sure you are using a version of PEAR which includes the Log classes, or that you have installed the Log package seperately. See the INSTALL file for instructions on installing Log.',
-        'required' => true,
-        'function' => '_check_pear_log_version'
-    ),
-    'DB' => array(
-        'path' => 'DB.php',
-        'error' => 'You will need DB if you are using SQL drivers for preferences, contacts (Turba), etc.',
-        'function' => '_check_pear_db_version'
-    ),
-    'MDB2' => array(
-        'path' => 'MDB2.php',
-        'error' => 'You will need MDB2 if you are using the SQL driver for Shares.',
-    ),
-    'Net_Socket' => array(
-        'path' => 'Net/Socket.php',
-        'error' => 'Make sure you are using a version of PEAR which includes the Net_Socket class, or that you have installed the Net_Socket package seperately. See the INSTALL file for instructions on installing Net_Socket.'
-    ),
-    'Date' => array(
-        'path' => 'Date/Calc.php',
-        'error' => 'Horde requires the Date_Calc class for Kronolith to calculate dates.'
-    ),
-    'Auth_SASL' => array(
-        'path' => 'Auth/SASL.php',
-        'error' => 'Horde will work without the Auth_SASL class, but if you use Access Control Lists in IMP you should be aware that without this class passwords will be sent to the IMAP server in plain text when retrieving ACLs.'
-    ),
-    'HTTP_Request' => array(
-        'path' => 'HTTP/Request.php',
-        'error' => 'Parts of Horde (Jonah, the XML-RPC client/server) use the HTTP_Request library to retrieve URLs and do other HTTP requests.'
-    ),
-    'HTTP_WebDAV_Server' => array(
-        'path' => 'HTTP/WebDAV/Server.php',
-        'error' => 'The HTTP_WebDAV_Server is required, if you want to use the WebDAV interface of Horde, e.g. to access calendars or tasklists with external clients.'
-    ),
-    'Net_SMTP' => array(
-        'path' => 'Net/SMTP.php',
-        'error' => 'Make sure you are using the Net_SMTP module if you want "smtp" to work as a mailer option.'
-    ),
-    'Services_Weather' => array(
-        'path' => 'Services/Weather.php',
-        'error' => 'Services_Weather is used by the weather applet/block on the portal page.'
-    ),
-    'Cache' => array(
-        'path' => 'Cache.php',
-        'error' => 'Cache is used by the Services_Weather module on the weather applet/block on the portal page.'
-    ),
-    'XML_Serializer' => array(
-        'path' => 'XML/Serializer.php',
-        'error' => 'XML_Serializer is used by the Services_Weather module on the weather applet/block on the portal page.'
-    ),
-    'Net_DNS' => array(
-        'path' => 'Net/DNS.php',
-        'error' => 'Net_DNS can speed up hostname lookups against broken DNS servers.'
-    )
-);
-
-/* Additional check for PEAR Log module for its version. */
-function _check_pear_log_version()
-{
-    if (!defined('PEAR_LOG_INFO')) {
-        return 'Your version of Log is not recent enough.';
-    }
+$classname = ucfirst($app) . '_Test';
+if (!class_exists($classname)) {
+    echo '<h2 style="color:red">No tests found for ' . $app . ' [' . $app_name . '].</h2>';
+    exit;
 }
+$test_ob = new $classname();
 
-/* Additional check for PEAR DB module for its version. */
-function _check_pear_db_version()
-{
-    if (!defined('DB_PORTABILITY_LOWERCASE')) {
-        return 'Your version of DB is not recent enough.';
-    }
+/* Register a session. */
+if (!isset($_SESSION['horde_test_count'])) {
+    $_SESSION['horde_test_count'] = 0;
 }
 
-/* Required configuration files. */
-$file_list = array(
-    'config/conf.php' => null,
-    'config/mime_drivers.php' => null,
-    'config/nls.php' => null,
-    'config/prefs.php' => null,
-    'config/registry.php' => null
-);
-
-
-/* Get the status output now. */
-$module_output = $horde_test->phpModuleCheck($module_list);
-$setting_output = $horde_test->phpSettingCheck($setting_list);
-$pear_output = $horde_test->PEARModuleCheck($pear_list);
-$config_output = $horde_test->requiredFileCheck($file_list);
+/* Template location. */
+$test_templates = HORDE_TEMPLATES . '/test';
 
+/* Self URL. */
+$url = Horde::selfUrl();
+$self_url = $url->copy()->add('app', $app);
 
 /* Handle special modes. */
-if (!empty($_GET['mode'])) {
-    $url = !empty($_GET['url']) ? $_GET['url'] : 'test.php';
+switch (Horde_Util::getGet('mode')) {
+case 'extensions':
     echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">';
-    switch ($_GET['mode']) {
-    case 'extensions':
-        require TEST_TEMPLATES . 'extensions.inc';
-        exit;
+    require $test_templates . '/extensions.inc';
+    exit;
 
-    case 'phpinfo':
-        echo '<a href="' . htmlspecialchars($url) . '?mode=test">&lt;&lt; Back to test.php</a>';
-        phpinfo();
-        exit;
+case 'phpinfo':
+    echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">';
+    echo '<a href="' . htmlspecialchars($self_url) . '">&lt;&lt; Back to test.php</a>';
+    phpinfo();
+    exit;
 
-    case 'unregister':
-        unset($_SESSION['horde_test_count']);
-        ?>
-        <html>
-        <body>
       The test session has been unregistered.<br />
       <a href="test.php">Go back</a> to the test.php page.<br />
       </body>
       </html>
-        <?php
-        exit;
-    }
+case 'unregister':
+    echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">';
+    unset($_SESSION['horde_test_count']);
+?>
+<html>
<body>
The test session has been unregistered.<br />
<a href="$self_url">Go back</a> to the test.php page.<br />
</body>
+</html>
+<?php
+    exit;
 }
 
-$test_app = 'horde';
-require TEST_TEMPLATES . 'header.inc';
-require TEST_TEMPLATES . 'version.inc';
+/* Get the status output now. */
+$module_output = $test_ob->phpModuleCheck();
+$setting_output = $test_ob->phpSettingCheck();
+$pear_output = $test_ob->pearModuleCheck();
+$config_output = $test_ob->requiredFileCheck();
+
+require $test_templates . '/header.inc';
+require $test_templates . '/version.inc';
 
+if ($app == 'horde') {
 ?>
-
 <h1>Horde Applications</h1>
 <ul>
 <?php
 
-/* Get Horde module version information. */
-$modules = $horde_test->applicationList();
-foreach ($modules as $app => $val) {
-    $app = ucfirst($app);
-    echo '<li>' . $app . ': ' . $val->version;
-    if (isset($val->test)) {
-        echo ' (<a href="' . $val->test . '">run ' . $app . ' tests</a>)';
+    /* Get Horde module version information. */
+    $app_list = $registry->listApps(null, true);
+    unset($app_list[$app]);
+    ksort($app_list);
+    foreach (array_keys($app_list) as $val) {
+        echo '<li>' . ucfirst($val) . ' [' . $registry->get('name', $val) . ']: ' . $registry->getVersion($val) .
+            ' (<a href="' . $url->copy()->add('app', $val) . "\">run tests</a>)</li>\n";
     }
-    echo "</li>\n";
-}
 
 ?>
 </ul>
-
 <?php
+} else {
+?>
+<h1>Other Horde Applications</h1>
+<ul>
+ <?php echo $test_ob->requiredAppCheck(); ?>
+</ul>
+<?php
+}
 
 /* Display PHP Version information. */
-$php_info = $horde_test->getPhpVersionInformation();
-require TEST_TEMPLATES . 'php_version.inc';
+$php_info = $test_ob->getPhpVersionInformation();
+require $test_templates . '/php_version.inc';
 
 ?>
 
 <h1>PHP Module Capabilities</h1>
 <ul>
   <?php echo $module_output ?>
+ <?php echo $module_output ?>
 </ul>
 
 <h1>Miscellaneous PHP Settings</h1>
 <ul>
-    <?php echo $setting_output ?>
-</ul>
-
-<h1>File Uploads</h1>
-<ul>
-    <?php echo $horde_test->phpSettingCheck(array('file_uploads' => array('setting' => true, 'error' => 'file_uploads must be enabled for some features like sending emails with IMP.' ))) ?>
-<?php if ($dir = ini_get('upload_tmp_dir')): ?>
-    <li>upload_tmp_dir: <strong style="color:"<?php echo is_writable($dir) ? 'green' : 'red' ?>"><?php echo $dir ?></strong></li>
-<?php endif; ?>
-    <li>upload_max_filesize: <?php echo ini_get('upload_max_filesize') ?></li>
-    <li>post_max_size: <?php echo ini_get('post_max_size') ?><br />
-    This value should be several times the expect largest upload size (notwithstanding any upload limits present in an application). Any upload that exceeds this size will cause any state information sent along with the uploaded data to be lost. This is a PHP limitation and can not be worked around.</li>
+ <?php echo $setting_output ?>
 </ul>
 
 <h1>Required Horde Configuration Files</h1>
@@ -370,8 +152,8 @@ require TEST_TEMPLATES . 'php_version.inc';
 <h1>PHP Sessions</h1>
 <?php $_SESSION['horde_test_count']++; ?>
 <ul>
   <li>Session counter: <?php echo $_SESSION['horde_test_count']; ?> [refresh the page to increment the counter]</li>
   <li>To unregister the session: <a href="test.php?mode=unregister">click here</a></li>
<li>Session counter: <?php echo $_SESSION['horde_test_count'] ?> [refresh the page to increment the counter]</li>
<li>To unregister the session: <a href="<?php $self_url->copy()->add('mode', 'unregister') ?>">click here</a></li>
 </ul>
 
 <h1>PEAR</h1>
@@ -381,19 +163,7 @@ require TEST_TEMPLATES . 'php_version.inc';
 
 <?php
 
-/* Determine if 'static' is writable by the web user. */
-if (is_writable(HORDE_BASE . '/static')) {
-    $writable = 'Yes';
-} else {
-    $writable = "<strong style=\"color:red\">No</strong><br /><strong style=\"color:orange\">If caching javascript and CSS files by storing them in static files (HIGHLY RECOMMENDED), this directory must be writable as the user the web server runs as.</strong>";
-}
-
-?>
+/* Do application specifc tests now. */
+echo $test_ob->appTests();
 
-<h1>Local File Permissions</h1>
-<ul>
-    <li>Is <tt><?php echo HORDE_BASE ?>/static</tt> writable by the web server user? <?php echo $writable ?></li>
-</ul>
-
-<?php
-require TEST_TEMPLATES . 'footer.inc';
+require $test_templates . '/footer.inc';
diff --git a/imp/lib/Test.php b/imp/lib/Test.php
new file mode 100644 (file)
index 0000000..227b055
--- /dev/null
@@ -0,0 +1,199 @@
+<?php
+/**
+ * The IMP_Test:: class provides the IMP configuration for the test script.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Michael Slusarz <slusarz@horde.org>
+ * @package IMP
+ */
+class IMP_Test extends Horde_Test
+{
+    /**
+     * The module list
+     *
+     * @var array
+     */
+    protected $_moduleList = array();
+
+    /**
+     * PHP settings list.
+     *
+     * @var array
+     */
+    protected $_settingsList = array(
+        'file_uploads'  =>  array(
+            'error' => 'file_uploads must be enabled to use various features of IMP. See the INSTALL file for more information.',
+            'setting' => true
+        )
+    );
+
+    /**
+     * PEAR modules list.
+     *
+     * @var array
+     */
+    protected $_pearList = array(
+        'Auth_SASL' => array(
+            'path' => 'Auth/SASL.php',
+            'error' => 'If your IMAP server uses CRAM-MD5 or DIGEST-MD5 authentication, this module is required.'
+        )
+    );
+
+    /**
+     * Required configuration files.
+     *
+     * @var array
+     */
+    protected $_fileList = array(
+        'config/conf.php' => 'The file <code>./config/conf.php</code> appears to be missing. You must generate this file as an administrator via Horde.  See horde/docs/INSTALL.',
+        'config/mime_drivers.php' => null,
+        'config/prefs.php' => null,
+        'config/servers.php' => null
+    );
+
+    /**
+     * Inter-Horde application dependencies.
+     *
+     * @var array
+     */
+    protected $_appList = array(
+        'gollem' => array(
+            'error' => 'Gollem provides access to local VFS filesystems to attach files.',
+            'version' => '2.0'
+        ),
+        'ingo' => array(
+            'error' => 'Ingo provides basic mail filtering capabilities to IMP.',
+            'version' => '2.0'
+        ),
+        'nag' => array(
+            'error' => 'Nag allows tasks to be directly created from e-mail data.',
+            'version' => '3.0'
+        ),
+        'turba' => array(
+            'error' => 'Turba provides addressbook/contacts capabilities to IMP.',
+            'version' => '3.0'
+        )
+    );
+
+    /**
+     * Any application specific tests that need to be done.
+     *
+     * @return string  HTML output.
+     */
+    public function appTests()
+    {
+        $ret = '<h1>Mail Server Support Test</h1>';
+
+        if (Horde_Util::getPost('user') && Horde_Util::getPost('passwd')) {
+            $ret .= $this->_doConnectionTest();
+        }
+
+        $self_url = Horde::selfUrl()->add('app', 'imp');
+
+        return $ret . Horde_Util::bufferOutput('require', IMP_TEMPLATES . '/test/mailserver.inc');
+    }
+
+    /**
+     * Perform mail server support test.
+     *
+     * @return string  HTML output.
+     */
+    protected function _doConnectionTest()
+    {
+        $imap_config = array(
+            'username' => Horde_Util::getPost('user'),
+            'password' => Horde_Util::getPost('passwd'),
+            'hostspec' => Horde_Util::getPost('server'),
+            'port' => Horde_Util::getPost('port'),
+            'secure' => Horde_Util::getPost('encrypt')
+        );
+
+        $driver = (Horde_Util::getPost('server_type') == 'imap')
+            ? 'Socket'
+            : 'Socket_Pop3';
+
+        try {
+            $imap_client = Horde_Imap_Client::factory($driver, $imap_config);
+        } catch (Horde_Imap_Client_Exception $e) {
+            return $this->_errorMsg($e);
+        }
+
+        $ret = '<strong>Attempting to login to the server:</strong> ';
+
+        try {
+            $imap_client->login();
+        } catch (Horde_Imap_Client_Exception $e) {
+            return $this->_errorMsg($e);
+        }
+
+        $ret .= '<span style="color:green">SUCCESS</span><p />';
+
+        if ($driver == 'Socket') {
+            $ret .= '<strong>The following IMAP server information was discovered from the remote server:</strong>' .
+                '<blockquote><em>Namespace Information</em><blockquote><pre>';
+
+            try {
+                $namespaces = $imap_client->getNamespaces();
+                foreach ($namespaces as $val) {
+                    $ret .= 'NAMESPACE: "' . htmlspecialchars($val['name']) . "\"\n" .
+                        'DELIMITER: ' . htmlspecialchars($val['delimiter']) . "\n" .
+                        'TYPE: ' . htmlspecialchars($val['type']) . "\n\n";
+                }
+            } catch (Horde_Imap_Client_Exception $e) {
+                $this->_errorMsg($e);
+            }
+
+            $ret .= '</pre></blockquote></blockquote>' .
+                '<blockquote><em>IMAP server capabilities:</em><blockquote><pre>';
+
+            try {
+                foreach ($imap_client->capability() as $key => $val) {
+                    if (is_array($val)) {
+                        foreach ($val as $val2) {
+                            $ret .= htmlspecialchars($key) . '=' . htmlspecialchars($val2) . "\n";
+                        }
+                    } else {
+                        $ret .= htmlspecialchars($key) . "\n";
+                    }
+                }
+            } catch (Horde_Imap_Client_Exception $e) {
+                $this->_errorMsg($e);
+            }
+
+            $ret .= '</pre></blockquote></blockquote>';
+
+            try {
+                $id_info = $imap_client->getID();
+                if (!empty($id_info)) {
+                    $ret .= '<blockquote><em>IMAP server information:</em><blockquote><pre>';
+                    foreach ($id_info as $key => $val) {
+                        $ret .= htmlspecialchars("$key:  $val") . "\n";
+                    }
+                    $ret .= '</pre></blockquote></blockquote>';
+                }
+            } catch (Horde_Imap_Client_Exception $e) {
+                // Ignore a lack of the ID capability.
+            }
+
+            // @todo IMAP Charset Search Support
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Return error message from mail server testing.
+     *
+     * @return string  HTML output.
+     */
+    protected function _errorMsg($e)
+    {
+        return '<span style=\"color:red\">ERROR</span> - The server returned the following error message:' .
+            '<pre>' . $e->getMessage() . '</pre><p />';
+    }
+
+}
diff --git a/imp/templates/test/mailserver.inc b/imp/templates/test/mailserver.inc
new file mode 100644 (file)
index 0000000..6086c26
--- /dev/null
@@ -0,0 +1,72 @@
+<form name="form1" method="post" action="<?php $self_url ?>">
+<table>
+ <tr>
+  <td align="right">
+   <label for="server">Server:</label>
+  </td>
+  <td>
+   <input type="text" id="server" name="server" />
+  </td>
+  <td>
+   (If blank, attempts to connects to a server running on the same machine as IMP)
+  </td>
+ </tr>
+ <tr>
+  <td align="right">
+   <label for="port">Port:</label>
+  </td>
+  <td>
+   <input type="text" id="port" name="port" />
+  </td>
+  <td>
+   (If non-standard port; leave blank to auto-detect using standard ports)
+  </td>
+ </tr>
+ <tr>
+  <td align="right">
+   <label for="user">User:</label>
+  </td>
+  <td>
+   <input type="text" id="user" name="user" />
+  </td>
+ </tr>
+ <tr>
+  <td align="right">
+   <label for="passwd">Password:</label>
+  </td>
+  <td>
+   <input type="password" id="passwd" name="passwd" />
+  </td>
+ </tr>
+ <tr>
+  <td align="right">
+   <label for="server_type">Server Type:</label>
+  </td>
+  <td>
+   <select id="server_type" name="server_type">
+    <option value="imap">IMAP4rev1</option>
+    <option value="pop">POP3</option>
+   </select>
+  </td>
+ </tr>
+ <tr>
+  <td align="right">
+   <label for="encrypt">Use SSL/TLS:</label>
+  </td>
+  <td>
+   <select id="encrypt" name="encrypt">
+    <option value="no">No</option>
+    <option value="ssl">SSL</option>
+    <option value="tls">TLS</option>
+   </select>
+  </td>
+ </tr>
+ <tr>
+  <td></td>
+  <td>
+   <input type="submit" name="f_submit" value="Submit" />
+   <input type="reset" name="f_reset" value="Reset" />
+  </td>
+ </tr>
+</table>
+</form>
diff --git a/imp/test.php b/imp/test.php
deleted file mode 100644 (file)
index dd88d86..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-<?php
-/**
- * IMP test script.
- *
- * Copyright 1999-2009 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author  Brent J. Nordquist <bjn@horde.org>
- * @author  Chuck Hagenbuch <chuck@horde.org>
- * @author  Michael Slusarz <slusarz@horde.org>
- * @package IMP
- */
-
-function _doConnectionTest()
-{
-    $imap_config = array(
-        'username' => isset($_POST['user']) ? $_POST['user'] : '',
-        'password' => isset($_POST['passwd']) ? $_POST['passwd'] : '',
-        'hostspec' => isset($_POST['server']) ? $_POST['server'] : '',
-        'port' => isset($_POST['port']) ? $_POST['port'] : '',
-        'secure' => ($_POST['port'] == 'yes')
-    );
-
-    $driver = ($_POST['server_type'] == 'imap') ? 'Socket' : 'Socket_Pop3';
-
-    try {
-        $imap_client = Horde_Imap_Client::factory($driver, $imap_config);
-    } catch (Horde_Imap_Client_Exception $e) {
-        return _errorMsg($e);
-    }
-
-    echo "<strong>Attempting to login to the server:</strong>\n";
-
-    try {
-        $imap_client->login();
-    } catch (Horde_Imap_Client_Exception $e) {
-        return _errorMsg($e);
-    }
-
-    echo '<span style="color:green">SUCCESS</span><p />';
-
-    if ($driver == 'Socket') {
-        echo "<strong>The following IMAP server information was discovered from the remote server:</strong>\n" .
-            "<blockquote><em>Namespace Information</em><blockquote><pre>";
-
-        try {
-            $namespaces = $imap_client->getNamespaces();
-            foreach ($namespaces as $val) {
-                echo "NAMESPACE: \"" . htmlspecialchars($val['name']) . "\"\n";
-                echo "DELIMITER: " . htmlspecialchars($val['delimiter']) . "\n";
-                echo "TYPE: " . htmlspecialchars($val['type']) . "\n\n";
-            }
-        } catch (Horde_Imap_Client_Exception $e) {
-            _errorMsg($e);
-        }
-
-        echo "</pre></blockquote></blockquote>\n" .
-            "<blockquote><em>IMAP server capabilities:</em><blockquote><pre>";
-
-        try {
-            foreach ($imap_client->capability() as $key => $val) {
-                if (is_array($val)) {
-                    foreach ($val as $val2) {
-                        echo htmlspecialchars($key) . '=' . htmlspecialchars($val2) . "\n";
-                    }
-                } else {
-                    echo htmlspecialchars($key) . "\n";
-                }
-            }
-        } catch (Horde_Imap_Client_Exception $e) {
-            _errorMsg($e);
-        }
-
-        echo "</pre></blockquote></blockquote>\n";
-
-        try {
-            $id_info = $imap_client->getID();
-            if (!empty($id_info)) {
-                echo "<blockquote><em>IMAP server information:</em><blockquote><pre>";
-                foreach ($id_info as $key => $val) {
-                    echo htmlspecialchars("$key:  $val") . "\n";
-                }
-                echo "</pre></blockquote></blockquote>\n";
-            }
-        } catch (Horde_Imap_Client_Exception $e) {
-            // Ignore a lack of the ID capability.
-        }
-
-        // @todo IMAP Charset Search Support
-    }
-}
-
-function _errorMsg($e)
-{
-    echo "<span style=\"color:red\">ERROR</span> - The server returned the following error message:\n" .
-        '<pre>' . $e->getMessage() . '</pre><p />';
-}
-
-
-/* Include Horde's core.php file. */
-require_once dirname(__FILE__) . '/lib/Application.php';
-
-/* We should have loaded the Horde_String class, from the Horde_Util
- * package, in core.php. If Horde_String:: isn't defined, then we're not
- * finding some critical libraries. */
-if (!class_exists('Horde_String')) {
-    echo '<br /><h2 style="color:red">The Horde_Util package was not found. If PHP\'s error_reporting setting is high enough and display_errors is on, there should be error messages printed above that may help you in debugging the problem. If you are simply missing these files, then you need to get the <a href="http://cvs.horde.org/cvs.php/framework">framework</a> module from <a href="http://www.horde.org/source/">Horde CVS</a>, and install the packages in it with the install-packages.php script.</h2>';
-    exit;
-}
-
-/* Initialize the Horde_Test:: class. */
-if (!is_readable(HORDE_BASE . '/lib/Test.php')) {
-    echo 'ERROR: You must install Horde before running this script.';
-    exit;
-}
-
-require_once HORDE_BASE . '/lib/Test.php';
-$horde_test = new Horde_Test();
-
-/* IMP version. */
-$module = 'IMP';
-$app = new IMP_Application();
-$module_version = $app->version;
-
-require TEST_TEMPLATES . 'header.inc';
-require TEST_TEMPLATES . 'version.inc';
-
-/* Display versions of other Horde applications. */
-$app_list = array(
-    'gollem' => array(
-        'error' => 'Gollem provides access to local VFS filesystems to attach files.',
-        'version' => '2.0'
-    ),
-    'ingo' => array(
-        'error' => 'Ingo provides basic mail filtering capabilities to IMP.',
-        'version' => '2.0'
-    ),
-    'nag' => array(
-        'error' => 'Nag allows tasks to be directly created from e-mail data.',
-        'version' => '3.0'
-    ),
-    'turba' => array(
-        'error' => 'Turba provides addressbook/contacts capabilities to IMP.',
-        'version' => '3.0'
-    )
-);
-$app_output = $horde_test->requiredAppCheck($app_list);
-
-?>
-<h1>Other Horde Applications</h1>
-<ul>
-    <?php echo $app_output ?>
-</ul>
-<?php
-
-/* Display PHP Version information. */
-$php_info = $horde_test->getPhpVersionInformation();
-require TEST_TEMPLATES . 'php_version.inc';
-
-/* PHP settings. */
-$setting_list = array(
-    'file_uploads'  =>  array(
-        'setting' => true,
-        'error' => 'file_uploads must be enabled to use various features of IMP. See the INSTALL file for more information.'
-    )
-);
-
-/* IMP configuration files. */
-$file_list = array(
-    'config/conf.php' => 'The file <code>./config/conf.php</code> appears to be missing. You must generate this file as an administrator via Horde.  See horde/docs/INSTALL.',
-    'config/mime_drivers.php' => null,
-    'config/prefs.php' => null,
-    'config/servers.php' => null
-);
-
-/* PEAR/PECL modules. */
-$pear_list = array(
-    'Auth_SASL' => array(
-        'path' => 'Auth/SASL.php',
-        'error' => 'If your IMAP server uses CRAM-MD5 or DIGEST-MD5 authentication, this module is required.'
-    )
-);
-
-/* Get the status output now. */
-$setting_output = $horde_test->phpSettingCheck($setting_list);
-$file_output = $horde_test->requiredFileCheck($file_list);
-$pear_output = $horde_test->PEARModuleCheck($pear_list);
-
-?>
-
-<h1>Miscellaneous PHP Settings</h1>
-<ul>
-    <?php echo $setting_output ?>
-</ul>
-
-<h1>Required IMP Configuration Files</h1>
-<ul>
-    <?php echo $file_output ?>
-</ul>
-
-<h1>PEAR</h1>
-<ul>
-    <?php echo $pear_output ?>
-</ul>
-
-<h1>PHP Mail Server Support Test</h1>
-<?php
-if (isset($_POST['user']) && isset($_POST['passwd'])) {
-    _doConnectionTest();
-}
-?>
-
-<form name="form1" method="post" action="test.php">
-<table>
-<tr><td align="right"><label for="server">Server:</label></td><td><input type="text" id="server" name="server" /></td><td>(If blank, attempts to connects to a server running on the same machine as IMP)</td></tr>
-<tr><td align="right"><label for="port">Port:</label></td><td><input type="text" id="port" name="port" /></td><td>(If non-standard port; leave blank to auto-detect using standard ports)</td></tr>
-<tr><td align="right"><label for="user">User:</label></td><td><input type="text" id="user" name="user" /></td></tr>
-<tr><td align="right"><label for="passwd">Password:</label></td><td><input type="password" id="passwd" name="passwd" /></td></tr>
-<tr><td align="right"><label for="server_type">Server Type:</label></td><td><select id="server_type" name="server_type"><option value="imap">IMAP4rev1</option><option value="pop">POP3</option></select></td></tr>
-<tr><td align="right"><label for="encrypt">Use SSL/TLS:</label></td><td><select id="encrypt" name="encrypt"><option value="no">No</option><option value="ssl">SSL</option><option value="tls">TLS</option></select></td></tr>
-<tr><td></td><td><input type="submit" name="f_submit" value="Submit" /><input type="reset" name="f_reset" value="Reset" /></td></tr>
-</table>
-</form>
-
-<?php
-require TEST_TEMPLATES . 'footer.inc';