root/trunk/mt-check.cgi

Revision 3112, 19.1 kB (checked in by fumiakiy, 2 months ago)

Check if at least one DBD module is installed. BugId:81794

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #!/usr/bin/perl -w
2
3 # Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd.
4 # This program is distributed under the terms of the
5 # GNU General Public License, version 2.
6 #
7 # $Id$
8
9 use strict;
10 sub BEGIN {
11     my $dir;
12     if (eval { require File::Spec; 1; }) {
13         if (!($dir = $ENV{MT_HOME})) {
14             if ($0 =~ m!(.*[/\\])!) {
15                 $dir = $1;
16             } else {
17                 $dir = './';
18             }
19             $ENV{MT_HOME} = $dir;
20         }
21         unshift @INC, File::Spec->catdir($dir, 'lib');
22         unshift @INC, File::Spec->catdir($dir, 'extlib');
23     }
24 }
25
26 my $cfg_exist;
27 my $mt_static_path = q();
28 my $mt_cgi_path;
29 if ((-f File::Spec->catfile($ENV{MT_HOME}, 'mt-config.cgi')) ||
30     (-f File::Spec->catfile($ENV{MT_HOME}, 'mt.cfg'))) {
31     $cfg_exist = 1;
32     my $file_handle = open(CFG, $ENV{MT_HOME}.'/mt.cfg') || open(CFG, $ENV{MT_HOME}.'/mt-config.cgi');
33     my $line;
34     while ($line = <CFG>) {
35         next if $line !~ /\S/ || $line =~ /^#/;
36         if ($line =~ s/StaticWebPath[\s]*([^\n]*)/$1/) {
37             $mt_static_path = $line;
38             chomp($mt_static_path);
39         }
40         elsif ($line =~ s/CGIPath[\s]*([^\n]*)/$1/) {
41             $mt_cgi_path = $line;
42             chomp($mt_cgi_path);
43         }
44     }
45     if ( !$mt_static_path && $mt_cgi_path ) {
46         $mt_cgi_path .= '/' if $mt_cgi_path !~ m|/$|;
47         $mt_static_path = $mt_cgi_path . 'mt-static/';
48     }
49 }
50
51 local $| = 1;
52
53 use CGI;
54 my $cgi = new CGI;
55 my $view = $cgi->param("view");
56 my $version = $cgi->param("version");
57 # $version ||= '__PRODUCT_VERSION_ID__';
58
59 my ($mt, $LH);
60 my $lang = $cgi->param("language") || $cgi->param("__lang");
61 eval {
62     require MT::App::Wizard;
63     $mt = MT::App::Wizard->new();
64    
65     require MT::Util;
66     $lang ||= MT::Util::browser_language();
67     my $cfg = $mt->config;
68     $cfg->PublishCharset('utf-8');
69     $cfg->DefaultLanguage($lang);
70     require MT::L10N;
71     if ( $mt ) {
72         $LH = $mt->language_handle;
73         $mt->set_language($lang);
74     }
75     else {
76         MT::L10N->get_handle($lang);
77     }
78 };
79
80 sub trans_templ {
81     my($text) = @_;
82     return $mt->translate_templatized($text) if $mt;
83     $text =~ s!(<MT_TRANS(?:\s+((?:\w+)\s*=\s*(["'])(?:<[^>]+?>|[^\3]+?)+?\3))+?\s*/?>)!
84         my($msg, %args) = ($1);
85         #print $msg;
86         while ($msg =~ /\b(\w+)\s*=\s*(["'])((?:<[^>]+?>|[^\2])*?)\2/g) {  #"
87             $args{$1} = $3;
88         }
89         $args{params} = '' unless defined $args{params};
90         my @p = map decode_html($_),
91                 split /\s*%%\s*/, $args{params};
92         @p = ('') unless @p;
93         my $translation = translate($args{phrase}, @p);
94         $translation =~ s/([\\'])/\\$1/sg if $args{escape};
95         $translation;
96     !ge;
97     $text;
98 }
99
100 sub translate {
101     return (
102         $mt ? $mt->translate(@_)
103             : $LH ? $LH->maketext(@_)
104                   : merge_params(@_)
105     );
106 }
107
108 sub decode_html {
109     my($html) = @_;
110     if ($cfg_exist && (eval 'use MT::Util; 1')) {
111         return MT::Util::decode_html($html);
112     } else {
113         $html =~ s#&quot;#"#g;
114         $html =~ s#&lt;#<#g;
115         $html =~ s#&gt;#>#g;
116         $html =~ s#&amp;#&#g;
117     }
118     $html;
119 }
120
121 sub merge_params {
122     my ($msg, @param) = @_;
123     my $cnt = 1;
124     foreach my $p (@param) {
125         $msg =~ s/\[_$cnt\]/$p/g;
126         $cnt++;
127     }
128     $msg;
129 }
130
131 print "Content-Type: text/html; charset=utf-8\n\n";
132 if (!$view) {
133     print trans_templ(<<HTML);
134
135 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
136 <html xmlns="http://www.w3.org/1999/xhtml">
137
138 <head>
139     <meta http-equiv="content-type" content="text/html; charset=utf-8" />
140     <meta http-equiv="content-language" content="$lang" />
141    
142     <title><MT_TRANS phrase="Movable Type System Check"> [mt-check.cgi]</title>
143    
144     <style type=\"text/css\">
145         <!--
146        
147             body {
148                 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
149                 font-size: 13px;
150                 margin: 0;
151                 padding: 0;
152                 background-color: #fff;
153             }
154            
155             body.has-static {
156                 background: #fff url('$mt_static_path/images/chromeless/chromeless_top_bg.gif') repeat-x;
157             }
158            
159             body.has-static #header {
160                 background: url('$mt_static_path/images/chromeless/movable-type-logo.gif') no-repeat 25px 15px;
161                 height: 55px;
162             }
163            
164             #content {
165                 margin: 20px 20px 100px;
166             }
167            
168             h1 {
169                 margin: 0;
170                 padding: 10px;
171                 text-align: center;
172                 font-size: 22px;
173                 color: #fff;
174                 background: #000;
175             }
176             body.has-static #header h1 {
177                 display: none;
178             }
179            
180             h2 {
181                 margin-top: 2em;
182                 margin-bottom: .5em;
183                 font-size: 24px;
184                 font-weight: normal;
185             }
186             h2#system-info {
187                 margin-top: 1em;
188             }
189            
190             h3 {
191                 color: #333;
192                 font-size: 16px;
193                 margin-bottom: 0px;
194             }
195    
196             p, ul {
197                 margin: 0 0 .75em 0;
198                 padding: 0;
199             }
200            
201             ul {
202                 padding-left: 20px;
203             }
204            
205             .msg {
206                 margin: 0 0 10px 0;
207                 padding: 16px 10px 16px 46px;
208                 background-repeat: no-repeat;
209             }
210             .msg-info {
211                 background-color: #eaf2ff;
212                 background-image: url('$mt_static_path/images/icon_info.gif');
213                 background-position: 12px center;
214                 border: 1px solid #999;
215             }
216
217                         .ready {
218                                 color: #fff;
219                                 background-color: #9C6;
220                 border: 0;
221                 padding-left: 5px;
222                         }
223
224             .msg-success {
225                 background-color: #CFC;
226                 background-image: url('$mt_static_path/images/icon_success.png');
227                 background-position: 12px .75em;
228                 font-size: 24px;
229             }
230             .msg-success h2 {
231                 margin-top: 0;
232             }
233             .msg-success p {
234                 font-size: 13px;
235             }
236
237             .info {
238                 margin-left: 60px;
239                 margin-right: 60px;
240                 padding: 20px;
241                 border: 1px solid #eaf2ff;
242                 background: #eaf2ff;
243                 color: #000;
244             }
245
246             .installed {
247                 color: #93b06b;
248                 padding-top: 0px;
249                 margin-top: 0px;
250             }
251
252             .warning {
253                 padding-top: 0px;
254                 margin-top: 4px;
255                 border-left: 1px solid red;
256                 padding-left: 10px;
257                 margin-left: 20px;
258             }
259            
260             ul.version {
261                 margin-bottom: 0;
262             }
263        
264         //-->
265     </style>
266
267 </head>
268
269 HTML
270     if ($mt_static_path) {
271         print "<body class=\"has-static\">\n";
272     } else {
273         print "<body>\n";
274     }
275     print trans_templ(<<HTML);
276 <div id="header"><h1><MT_TRANS phrase="Movable Type System Check"> [mt-check.cgi]</h1></div>
277
278 <div id="content">
279 <p class="msg msg-info"><MT_TRANS phrase="The mt-check.cgi script provides you with information on your system's configuration and determines whether you have all of the components you need to run Movable Type."></p>
280 HTML
281 }
282
283 my $is_good = 1;
284 my (@REQ, @DATA, @OPT);
285
286 my @CORE_REQ = (
287     [ 'CGI', 0, 1, translate('CGI is required for all Movable Type application functionality.') ],
288
289     [ 'Image::Size', 0, 1, translate('Image::Size is required for file uploads (to determine the size of uploaded images in many different formats).') ],
290
291     [ 'File::Spec', 0.8, 1, translate('File::Spec is required for path manipulation across operating systems.') ],
292
293     [ 'CGI::Cookie', 0, 1, translate('CGI::Cookie is required for cookie authentication.') ],
294 );
295
296 my @CORE_DATA = (
297     [ 'DBI', 1.21, 0, translate('DBI is required to store data in database.') ],
298
299     [ 'DBD::mysql', 0, 0, translate('DBI and DBD::mysql are required if you want to use the MySQL database backend.') ],
300
301     [ 'DBD::Pg', 1.32, 0, translate('DBI and DBD::Pg are required if you want to use the PostgreSQL database backend.') ],
302
303     [ 'DBD::SQLite', 0, 0, translate('DBI and DBD::SQLite are required if you want to use the SQLite database backend.') ],
304
305     [ 'DBD::SQLite2', 0, 0, translate('DBI and DBD::SQLite2 are required if you want to use the SQLite 2.x database backend.') ],
306
307 );
308
309 my @CORE_OPT = (
310     [ 'HTML::Entities', 0, 0, translate('HTML::Entities is needed to encode some characters, but this feature can be turned off using the NoHTMLEntities option in the configuration file.') ],
311
312     [ 'LWP::UserAgent', 0, 0, translate('LWP::UserAgent is optional; It is needed if you wish to use the TrackBack system, the weblogs.com ping, or the MT Recently Updated ping.') ],
313
314     [ 'HTML::Parser', 0, 0, translate('HTML::Parser is optional; It is needed if you wish to use the TrackBack system, the weblogs.com ping, or the MT Recently Updated ping.') ],
315
316     [ 'SOAP::Lite', 0.50, 0, translate('SOAP::Lite is optional; It is needed if you wish to use the MT XML-RPC server implementation.') ],
317
318     [ 'File::Temp', 0, 0, translate('File::Temp is optional; It is needed if you would like to be able to overwrite existing files when you upload.') ],
319
320     [ 'Scalar::Util', 0, 1, translate('Scalar::Util is optional; It is needed if you want to use the Publish Queue feature.')],
321
322     [ 'List::Util', 0, 1, translate('List::Util is optional; It is needed if you want to use the Publish Queue feature.')],
323
324     [ 'Image::Magick', 0, 0, translate('Image::Magick is optional; It is needed if you would like to be able to create thumbnails of uploaded images.') ],
325
326     [ 'Storable', 0, 0, translate('Storable is optional; it is required by certain MT plugins available from third parties.')],
327
328     [ 'Crypt::DSA', 0, 0, translate('Crypt::DSA is optional; if it is installed, comment registration sign-ins will be accelerated.')],
329
330     [ 'MIME::Base64', 0, 0, translate('MIME::Base64 is required in order to enable comment registration.')],
331
332     [ 'XML::Atom', 0, 0, translate('XML::Atom is required in order to use the Atom API.')],
333
334     [ 'Cache::Memcached', 0, 0, translate('Cache::Memcached and memcached server/daemon is required in order to use memcached as caching mechanism used by Movable Type.')],
335
336     [ 'Archive::Tar', 0, 0, translate('Archive::Tar is required in order to archive files in backup/restore operation.')],
337
338     [ 'IO::Compress::Gzip', 0, 0, translate('IO::Compress::Gzip is required in order to compress files in backup/restore operation.')],
339        
340     [ 'IO::Uncompress::Gunzip', 0, 0, translate('IO::Uncompress::Gunzip is required in order to decompress files in backup/restore operation.')],
341    
342     [ 'Archive::Zip', 0, 0, translate('Archive::Zip is required in order to archive files in backup/restore operation.')],
343
344     [ 'XML::SAX', 0, 0, translate('XML::SAX and/or its dependencies is required in order to restore.')],
345
346     [ 'Digest::SHA1', 0, 0, translate('Digest::SHA1 and its dependencies are required in order to allow commenters to be authenticated by OpenID providers including Vox and LiveJournal.')],
347     [ 'Mail::Sendmail', 0, 0, translate('Mail::Sendmail is required for sending mail via SMTP Server.')],
348     [ 'Safe', 0, 0, translate('This module is used in test attribute of MTIf conditional tag.')],
349     [ 'Digest::MD5', 0, 0, translate('This module is used by the Markdown text filter.')],
350     [ 'Text::Balanced', 0, 0, translate('This module is required in mt-search.cgi if you are running Movable Type on Perl older than Perl 5.8.') ],
351 );
352
353 use Cwd;
354 my $cwd = '';
355 {
356     my($bad);
357     local $SIG{__WARN__} = sub { $bad++ };
358     eval { $cwd = Cwd::getcwd() };
359     if ($bad || $@) {
360         eval { $cwd = Cwd::cwd() };
361         if ($@ && $@ !~ /Insecure \$ENV{PATH}/) {
362             die $@;
363         }
364     }
365 }
366
367 my $ver = ref($^V) eq 'version' ? $^V->normal : ( $^V ? join('.', unpack 'C*', $^V) : $] );
368 my $perl_ver_check = '';
369 if ($] < 5.006001) {  # our minimal requirement for support
370     $perl_ver_check = <<EOT;
371 <p class="warning"><MT_TRANS phrase="The version of Perl installed on your server ([_1]) is lower than the minimum supported version ([_2]). Please upgrade to at least Perl [_2]." params="$ver%%5.6.1"></p>
372 EOT
373 }
374 my $config_check = '';
375 if (!$cfg_exist) {
376     $config_check = <<CONFIG;
377 <p class="warning"><MT_TRANS phrase="Movable Type configuration file was not found."></p>
378 CONFIG
379 }
380 my $server = $ENV{SERVER_SOFTWARE};
381 my $inc_path = join "<br />\n", @INC;
382 print trans_templ(<<INFO);
383 <h2 id="system-info"><MT_TRANS phrase="System Information"></h2>
384 $perl_ver_check
385 $config_check
386 INFO
387 if ($version) {
388     # sanitize down to letters numbers dashes and period
389     $version =~ s/[^a-zA-Z0-9\-\.]//g;
390 print trans_templ(<<INFO);
391 <ul class="version">
392     <li><strong><MT_TRANS phrase="Movable Type version:"></strong> <code>$version</code></li>
393 </ul>
394 INFO
395 }
396 print trans_templ(<<INFO);
397 <ul>
398         <li><strong><MT_TRANS phrase="Current working directory:"></strong> <code>$cwd</code></li>
399         <li><strong><MT_TRANS phrase="MT home directory:"></strong> <code>$ENV{MT_HOME}</code></li>
400         <li><strong><MT_TRANS phrase="Operating system:"></strong> $^O</li>
401         <li><strong><MT_TRANS phrase="Perl version:"></strong> <code>$ver</code></li>
402         <li><strong><MT_TRANS phrase="Perl include path:"></strong><br /> <code>$inc_path</code></li>
403 INFO
404 if ($server) {
405 print trans_templ(<<INFO);
406     <li><strong><MT_TRANS phrase="Web server:"></strong> <code>$server</code></li>
407 INFO
408 }
409
410 ## Try to create a new file in the current working directory. This
411 ## isn't a perfect test for running under cgiwrap/suexec, but it
412 ## is a pretty good test.
413 my $TMP = "test$$.tmp";
414 local *FH;
415 if (open(FH, ">$TMP")) {
416     close FH;
417     unlink($TMP);
418     print trans_templ('    <li><MT_TRANS phrase="(Probably) Running under cgiwrap or suexec"></li>' . "\n");
419 }
420
421 print "\n\n</ul>\n";
422
423 exit if $ENV{QUERY_STRING} && $ENV{QUERY_STRING} eq 'sys-check';
424
425 if ($mt) {
426     my $req = $mt->registry("required_packages");
427     foreach my $key (keys %$req) {
428         next if $key eq 'DBI';
429         my $pkg = $req->{$key};
430         push @REQ, [ $key, $pkg->{version} || 0, 1, $pkg->{label}, $key, $pkg->{link} ];
431     }
432     my $drivers = $mt->object_drivers;
433     foreach my $key (keys %$drivers) {
434         my $driver = $drivers->{$key};
435         my $label = $driver->{label};
436         my $link = 'http://search.cpan.org/dist/' . $driver->{dbd_package};
437         $link =~ s/::/-/g;
438         push @DATA, [ $driver->{dbd_package}, $driver->{dbd_version}, 0,
439             $mt->translate("The [_1] database driver is required to use [_2].", $driver->{dbd_package}, $label),
440             $label, $link ];
441     }
442     unshift @DATA, [ 'DBI', 1.21, 0, translate('DBI is required to store data in database.') ]
443         if @DATA;
444     my $opt = $mt->registry("optional_packages");
445     foreach my $key (keys %$opt) {
446         my $pkg = $opt->{$key};
447         push @OPT, [ $key, $pkg->{version} || 0, 0, $pkg->{label}, $key, $pkg->{link} ];
448     }
449 }
450 @REQ  = @CORE_REQ  unless @REQ;
451 @DATA = @CORE_DATA unless @DATA;
452 @OPT  = @CORE_OPT  unless @OPT;
453
454 for my $list (\@REQ, \@DATA, \@OPT) {
455     my $data = ($list == \@DATA);
456     my $req = ($list == \@REQ);
457     my $type;
458     my $phrase;
459
460     if (!$view) {
461         $phrase = translate("Checking for");
462     } else {
463         $phrase = translate("Installed");
464     }
465
466     if ($data) {
467         $type = translate("Data Storage");
468     } elsif ($req) {
469         $type = translate("Required");
470     } else {
471         $type = translate("Optional");
472     }
473     print trans_templ(qq{<h2><MT_TRANS phrase="[_1] [_2] Modules" params="$phrase%%$type"></h2>\n\t<div>\n});
474     if (!$req && !$data) {
475         if (!$view) {
476         print trans_templ(<<MSG);
477     <p class="msg msg-info"><MT_TRANS phrase="The following modules are <strong>optional</strong>. If your server does not have these modules installed, you only need to install them if you require the functionality that the module provides."></p>
478
479 MSG
480        }
481     }
482     if ($data) {
483         if (!$view) {
484         print trans_templ(<<MSG);
485         <p class="msg msg-info"><MT_TRANS phrase="Some of the following modules are required by the various data storage options in Movable Type. In order run the system, your server needs to have DBI and at least one of the other modules installed."></p>
486
487 MSG
488         }
489     }
490     my $got_one_data = 0;
491     my $dbi_is_okay = 0;
492     for my $ref (@$list) {
493         my($mod, $ver, $req, $desc) = @$ref;
494         if ('CODE' eq ref($desc)) {
495             $desc = $desc->();
496         }
497         print "<blockquote>\n" if $mod =~ m/^DBD::/;
498         print "    <h3>$mod" .
499             ($ver ? " (version &gt;= $ver)" : "") . "</h3>";
500         eval("use $mod" . ($ver ? " $ver;" : ";"));
501         if ($@) {
502             $is_good = 0 if $req;
503             my $msg = $ver ?
504                       trans_templ(qq{<p class="warning"><MT_TRANS phrase="Either your server does not have [_1] installed, the version that is installed is too old, or [_1] requires another module that is not installed." params="$mod"> }) :
505                       trans_templ(qq{<p class="warning"><MT_TRANS phrase="Your server does not have [_1] installed, or [_1] requires another module that is not installed." params="$mod"> });
506             $msg   .= $desc .
507                       trans_templ(qq{ <MT_TRANS phrase="Please consult the installation instructions for help in installing [_1]." params="$mod"></p>\n\n});
508             print $msg . "\n\n";
509         } else {
510             if ($data) {
511                 $dbi_is_okay = 1 if $mod eq 'DBI';
512                 if ($mod eq 'DBD::mysql') {
513                     if ($DBD::mysql::VERSION == 3.0000) {
514                         print trans_templ(qq{<p class="warning"><MT_TRANS phrase="The DBD::mysql version you have installed is known to be incompatible with Movable Type. Please install the current release available from CPAN."></p>});
515                     }
516                 }
517                 if (!$dbi_is_okay) {
518                     print trans_templ(qq{<p class="warning"><MT_TRANS phrase="The $mod is installed properly, but requires an updated DBI module. Please see note above regarding the DBI module requirements."></p>});
519                 } else {
520                     $got_one_data = 1 if $mod ne 'DBI';
521                 }
522             }
523             print trans_templ(qq{<p class="installed"><MT_TRANS phrase="Your server has [_1] installed (version [_2])." params="$mod%%} . $mod->VERSION . qq{"></p>\n\n});
524         }
525         print "</blockquote>\n" if $mod =~ m/^DBD::/;
526     }
527     $is_good &= $got_one_data if $data;
528     print "\n\t</div>\n\n";
529 }
530
531 if ($is_good && $cfg_exist) {
532     if (!$view) {
533     print trans_templ(<<HTML);
534    
535     <div class="msg msg-success">
536         <h2><MT_TRANS phrase="Movable Type System Check Successful"></h2>
537         <p><strong><MT_TRANS phrase="You're ready to go!"></strong> <MT_TRANS phrase="Your server has all of the required modules installed; you do not need to perform any additional module installations. Continue with the installation instructions."></p>
538     </div>
539
540 </div>
541
542 HTML
543     }
544 }
545
546 print "</body>\n\n</html>\n";
Note: See TracBrowser for help on using the browser.