Minor change to freebusy report test.
[davical.git] / htdocs / setup.php
blob86604aa4f918f1bedcf6596afe6be0ed3c3a0046
1 <?php
2 /** todo work out something more than true/false returns for dependency checks */
4 function i18n($value) {
5 return $value; /* Just pass the value through */
8 class CheckResult {
9 private $ok;
10 private $use_class;
11 private $description;
13 function __construct( $success, $description=null, $use_class=null ) {
14 $this->ok = (boolean) $success;
15 $this->description = (isset($description)?$description : ($success===true? i18n('Passed') : i18n('Fail')));
16 $this->use_class = (isset($use_class)?$use_class:($success===true?'dep_ok' : 'dep_fail'));
19 public function getClass() {
20 return $this->use_class;
23 public function setClass( $new_class ) {
24 $this->use_class = $new_class;
27 public function getOK() {
28 return $this->ok;
31 public function getDescription() {
32 return translate($this->description);
35 public function setDescription( $new_desc ) {
36 $this->description = $new_desc;
41 /**
42 * We put many of these checks before we even try to load always.php so that we
43 * can try and do some diagnostic work to ensure it will load OK.
45 function check_pgsql() {
46 return new CheckResult(function_exists('pg_connect'));
49 function check_pdo() {
50 return new CheckResult(class_exists('PDO'));
53 function check_pdo_pgsql() {
54 global $loaded_extensions;
56 if ( !check_pdo() ) return new CheckResult(false);
57 return new CheckResult(isset($loaded_extensions['pdo_pgsql']));
60 function check_gettext() {
61 global $phpinfo, $loaded_extensions;
63 if ( !function_exists('gettext') ) return new CheckResult(false);
64 return new CheckResult(isset($loaded_extensions['gettext']));
67 function check_iconv() {
68 global $phpinfo, $loaded_extensions;
70 if ( !function_exists('iconv') ) return new CheckResult(false);
71 return new CheckResult(isset($loaded_extensions['iconv']));
74 function check_ldap() {
75 global $phpinfo, $loaded_extensions;
77 if (!function_exists('ldap_connect')) return new CheckResult(false);
78 return new CheckResult(isset($loaded_extensions['ldap']));
81 function check_real_php() {
82 global $phpinfo, $loaded_extensions;
83 // Looking for "Server API </td><td class="v">Apache 2.0 Filter" in the phpinfo
84 if ( preg_match('{Server API.*Apache 2\.. Filter}', $phpinfo) ) return new CheckResult(false);
85 return new CheckResult(true);
88 function check_calendar() {
89 global $phpinfo, $loaded_extensions;
91 if (!function_exists('cal_days_in_month')) return new CheckResult(false);
92 return new CheckResult(isset($loaded_extensions['calendar']));
95 function check_suhosin_server_strip() {
96 global $loaded_extensions;
98 if ( !isset($loaded_extensions['suhosin']) ) return new CheckResult(true);
99 return new CheckResult( ini_get('suhosin.server.strip') == "0" || strtolower(ini_get('suhosin.server.strip')) == "off" );
102 function check_magic_quotes_gpc() {
103 return new CheckResult( (get_magic_quotes_gpc() == 0) );
106 function check_magic_quotes_runtime() {
107 return new CheckResult( (get_magic_quotes_runtime() == 0) );
110 function check_curl() {
111 global $phpinfo, $loaded_extensions;
113 if (!function_exists('curl_init')) return new CheckResult(false);
114 return new CheckResult(isset($loaded_extensions['curl']));
117 $loaded_extensions = array_flip(get_loaded_extensions());
120 function do_error( $errormessage ) {
121 // We can't translate this because we're testing these things even before
122 // the translation interface is available...
123 printf("<p class='error'>%s</p>", $errormessage );
126 if ( !check_gettext()->getOK() ) do_error("The GNU 'gettext' extension for PHP is not available.");
127 if ( !check_pgsql()->getOK() ) do_error("PHP 'pgsql' functions are not available");
128 if ( !check_pdo()->getOK() ) do_error("PHP 'PDO' module is not available");
129 if ( !check_pdo_pgsql()->getOK() ) do_error("The PDO drivers for PostgreSQL are not available");
130 if ( !check_iconv()->getOK() ) do_error("The 'iconv' extension for PHP is not available");
132 function get_phpinfo() {
133 ob_start( );
134 phpinfo();
135 $phpinfo = ob_get_contents( );
136 ob_end_clean( );
138 $phpinfo = preg_replace( '{^.*?<body>}s', '', $phpinfo);
139 $phpinfo = preg_replace( '{</body>.*?$}s', '', $phpinfo);
140 return $phpinfo;
142 $phpinfo = get_phpinfo();
144 include("./always.php");
145 include("DAViCalSession.php");
148 if ( check_pgsql()->GetOK() ) {
149 $session->LoginRequired( (isset($c->restrict_setup_to_admin) && $c->restrict_setup_to_admin ? 'Admin' : null ) );
153 include("interactive-page.php");
154 include("page-header.php");
156 require_once("AwlQuery.php");
159 function check_datetime() {
160 if ( class_exists('DateTime') ) return new CheckResult(true);
161 $result = new CheckResult(false);
162 $result->setClass('dep_warning');
163 $result->setDescription(i18n('Most of DAViCal will work but upgrading to PHP 5.2 or later is strongly recommended.'));
164 return $result;
167 function check_schema_version() {
168 global $c;
169 if ( $c->want_dbversion[0] == $c->schema_major
170 && $c->want_dbversion[1] == $c->schema_minor
171 && $c->want_dbversion[2] == $c->schema_patch ) {
172 return new CheckResult( true );
174 $result = new CheckResult(false);
175 if ( $c->want_dbversion[0] < $c->schema_major
176 || ($c->want_dbversion[0] == $c->schema_major && $c->want_dbversion[1] < $c->schema_minor)
177 || ($c->want_dbversion[0] == $c->schema_major
178 && $c->want_dbversion[1] == $c->schema_minor
179 && $c->want_dbversion[2] < $c->schema_patch)
182 $result->setClass('dep_warning');
184 $result->setDescription( sprintf(i18n('Want: %s, Currently: %s'), implode('.',$c->want_dbversion),
185 $c->schema_major.'.'.$c->schema_minor.'.'.$c->schema_patch));
186 return $result;
189 function check_davical_version() {
190 global $c;
191 $url = 'http://www.davical.org/current_davical_version?v='.$c->version_string;
192 $version_file = @fopen($url, 'r');
193 if ( ! $version_file ) return new CheckResult( false, translate("Could not retrieve") . " '$url'", 'dep_warning' );
194 $current_version = trim(fread( $version_file,12));
195 fclose($version_file);
196 $result = new CheckResult($c->version_string == $current_version);
197 if ( ! $result->getOK() ) {
198 $result->setDescription( sprintf(i18n('Want: %s, Currently: %s'), $current_version, $c->version_string) );
199 if ( $c->version_string > $current_version ) $result->setClass('dep_warning');
201 return $result;
205 function check_awl_version() {
206 global $c;
208 if ( !function_exists('awl_version') ) return new CheckResult(false);
210 $result = new CheckResult($c->want_awl_version == awl_version());
211 if ( ! $result->getOK() ) {
212 $result->setDescription( sprintf(i18n('Want: %s, Currently: %s'), $c->want_awl_version, awl_version()) );
213 if ( $c->want_awl_version < awl_version() ) $result->setClass('dep_warning');
215 return $result;
220 function build_site_statistics() {
221 $principals = translate('No. of Principals');
222 $collections = translate('No. of Collections');
223 $resources = translate('No. of Resources');
224 $table = <<<EOTABLE
225 <table class="statistics">
226 <tr><th>$principals</th><th>$collections</th><th>$resources</th></tr>
227 <tr>%s</tr>
228 </table>
229 EOTABLE;
231 if ( !check_pdo_pgsql() ) {
232 return sprintf( $table, '<td colspan="3">'.translate('Site Statistics require the database to be available!').'</td>');
234 $sql = 'SELECT
235 (SELECT count(1) FROM principal) AS principals,
236 (SELECT count(1) FROM collection) AS collections,
237 (SELECT count(1) FROM caldav_data) AS resources';
238 $qry = new AwlQuery($sql);
239 if ( $qry->Exec('setup',__LINE__,__FILE__) && $s = $qry->Fetch() ) {
240 $row = sprintf('<td align="center">%s</td><td align="center">%s</td><td align="center">%s</td>',
241 $s->principals, $s->collections, $s->resources );
242 return sprintf( $table, $row );
244 return sprintf( $table, '<td colspan="3">'.translate('Site Statistics require the database to be available!').'</td>');
248 function build_dependencies_table( ) {
249 global $c;
251 $dependencies = array(
252 translate('Current DAViCal version ') => 'check_davical_version',
253 translate('DAViCal DB Schema version ') => 'check_schema_version',
254 translate('AWL Library version ') => 'check_awl_version',
255 translate('PHP not using Apache Filter mode') => 'check_real_php',
256 translate('PHP PDO module available') => 'check_pdo',
257 translate('PDO PostgreSQL drivers') => 'check_pdo_pgsql',
258 // translate('PHP PostgreSQL available') => 'check_pgsql',
259 translate('GNU gettext support') => 'check_gettext',
260 translate('PHP iconv support') => 'check_iconv',
261 translate('PHP DateTime class') => 'check_datetime',
262 translate('Suhosin "server.strip" disabled') => 'check_suhosin_server_strip',
263 translate('PHP Magic Quotes GPC off') => 'check_magic_quotes_gpc',
264 translate('PHP Magic Quotes runtime off') => 'check_magic_quotes_runtime',
265 translate('PHP calendar extension available') => 'check_calendar',
266 translate('PHP curl support') => 'check_curl'
269 if ( isset($c->authenticate_hook) && isset($c->authenticate_hook['call']) && $c->authenticate_hook['call'] == 'LDAP_check') {
270 $dependencies[translate('PHP LDAP module available')] = 'check_ldap';
273 $dependencies_table = '';
274 $dep_tpl = '<tr class="%s">
275 <td>%s</td>
276 <td>%s</td>
277 <td><a href="http://wiki.davical.org/w/Setup_Failure_Codes/%s">Explanation on DAViCal Wiki</a></td>
278 </tr>
280 foreach( $dependencies AS $k => $v ) {
281 $check_result = $v();
282 $dependencies_table .= sprintf( $dep_tpl, $check_result->getClass(),
284 $check_result->getDescription(),
285 rawurlencode($k)
289 return $dependencies_table;
293 $heading_setup = translate('Setup');
294 $paragraph_setup = translate('This page primarily checks the environment needed for DAViCal to work correctly. Suggestions or patches to make it do more useful stuff will be gratefully received.');
297 $want_dbversion = implode('.',$c->want_dbversion);
298 $heading_versions = translate('Current Versions');
299 if ( check_schema_version() != true )
301 $paragraph_versions = translate('You are currently running DAViCal version %s. The database schema should be at version %s and it is at version %d.%d.%d.');
302 $paragraph_versions = sprintf( $paragraph_versions, $c->version_string, $want_dbversion, $c->schema_major, $c->schema_minor, $c->schema_patch);
303 } else {
304 $paragraph_versions = translate('You are currently running DAViCal version %s. The database schema is at version %d.%d.%d.');
305 $paragraph_versions = sprintf( $paragraph_versions, $c->version_string, $c->schema_major, $c->schema_minor, $c->schema_patch);
309 $heading_dependencies = translate('Dependencies');
310 $th_dependency = translate('Dependency');
311 $th_status = translate('Status');
312 $dependencies_table = build_dependencies_table();
314 $heading_site_statistics = translate('Site Statistics');
315 $site_statistics_table = build_site_statistics();
317 $heading_config_clients = translate('Configuring Calendar Clients for DAViCal');
318 $heading_config_davical = translate('Configuring DAViCal');
319 $davical_configuration_errors = ( $config_warnings == '' ? '' : '<div class="error"><h3 class="error">'
320 . translate('Your configuration produced PHP errors which should be corrected') . '</h3><pre>'
321 . $config_warnings.'</pre></div>'
325 echo <<<EOBODY
326 <style>
327 tr.dep_ok {
328 background-color:#80ff80;
330 tr.dep_fail {
331 background-color:#ff8080;
333 tr.dep_warning {
334 background-color:#ffb040;
336 table, table.dependencies {
337 border: 1px grey solid;
338 border-collapse: collapse;
339 padding: 0.1em;
340 margin: 0 1em 1.5em;
342 table tr td, table tr th, table.dependencies tr td, table.dependencies tr th {
343 border: 1px grey solid;
344 padding: 0.1em 0.2em;
347 padding: 0.3em 0.2em 0.7em;
349 </style>
351 <h1>$heading_setup</h1>
352 <p>$paragraph_setup
354 <h2>$heading_dependencies</h2>
356 <table class="dependencies">
357 <tr>
358 <th>$th_dependency</th>
359 <th>$th_status</th>
360 </tr>
361 $dependencies_table
362 </table>
363 </p>
364 <h2>$heading_config_davical</h2>
365 <p>If you can read this then things must be mostly working already.</p>
366 $davical_configuration_errors
367 <p>The <a href="http://www.davical.org/installation.php">installation page on the DAViCal website</a> has
368 some further information on how to install and configure this application.</p>
370 <h2>$heading_config_clients</h2>
371 <p>The <a href="http://www.davical.org/clients.php">client setup page on the DAViCal website</a> has information on how
372 to configure Evolution, Sunbird, Lightning and Mulberry to use remotely hosted calendars.</p>
373 <p>The administrative interface has no facility for viewing or modifying calendar data.</p>
375 <h2>$heading_site_statistics</h2>
376 <p>$site_statistics_table</p>
378 <h2>PHP Information</h2>
379 <script language="javascript">
380 function toggle_visible() {
381 var argv = toggle_visible.arguments;
382 var argc = argv.length;
384 var fld_checkbox = document.getElementById(argv[0]);
386 if ( argc < 2 ) {
387 return;
390 for (var i = 1; i < argc; i++) {
391 var block_id = argv[i].substr(1);
392 var block_logical = argv[i].substr(0,1);
393 var b = document.getElementById(block_id);
394 if ( block_logical == '!' )
395 b.style.display = (fld_checkbox.checked ? 'none' : '');
396 else
397 b.style.display = (!fld_checkbox.checked ? 'none' : '');
400 </script><p><label>Show phpinfo() output:<input type="checkbox" value="1" id="fld_show_phpinfo" onclick="toggle_visible('fld_show_phpinfo','=phpinfo')"></label></p>
401 <div style="display:none" id="phpinfo">$phpinfo</div>
403 EOBODY;
405 include("page-footer.php");