| 1 | # Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd. |
|---|
| 2 | # This program is distributed under the terms of the |
|---|
| 3 | # GNU General Public License, version 2. |
|---|
| 4 | # |
|---|
| 5 | # $Id$ |
|---|
| 6 | |
|---|
| 7 | package MT::Bootstrap; |
|---|
| 8 | |
|---|
| 9 | use strict; |
|---|
| 10 | |
|---|
| 11 | sub BEGIN { |
|---|
| 12 | my ($dir, $orig_dir); |
|---|
| 13 | require File::Spec; |
|---|
| 14 | if (!($dir = $ENV{MT_HOME})) { |
|---|
| 15 | if ($0 =~ m!(.*([/\\]))!) { |
|---|
| 16 | $orig_dir = $dir = $1; |
|---|
| 17 | my $slash = $2; |
|---|
| 18 | $dir =~ s!(?:[/\\]|^)(?:plugins[/\\].*|tools[/\\])$!$slash!; |
|---|
| 19 | $dir = '' if ($dir =~ m!^\.?[\\/]$!); |
|---|
| 20 | } elsif ($] >= 5.006) { |
|---|
| 21 | # MT_DIR/lib/MT/Bootstrap.pm -> MT_DIR/lib/MT -> MT_DIR/lib -> MT_DIR |
|---|
| 22 | require File::Basename; |
|---|
| 23 | $dir = File::Basename::dirname(File::Basename::dirname( |
|---|
| 24 | File::Basename::dirname(File::Spec->rel2abs(__FILE__)))); |
|---|
| 25 | } |
|---|
| 26 | unless ($dir) { |
|---|
| 27 | $orig_dir = $dir = $ENV{PWD} || '.'; |
|---|
| 28 | $dir =~ s!(?:[/\\]|^)(?:plugins[/\\].*|tools[/\\]?)$!!; |
|---|
| 29 | } |
|---|
| 30 | $ENV{MT_HOME} = $dir; |
|---|
| 31 | } |
|---|
| 32 | unshift @INC, File::Spec->catdir($dir, 'extlib'); |
|---|
| 33 | unshift @INC, File::Spec->catdir($orig_dir, 'lib') |
|---|
| 34 | if $orig_dir && ($orig_dir ne $dir); |
|---|
| 35 | } |
|---|
| 36 | |
|---|
| 37 | sub import { |
|---|
| 38 | my ($pkg, %param) = @_; |
|---|
| 39 | |
|---|
| 40 | # use 'App' parameter, or MT_APP from the environment |
|---|
| 41 | my $class = $param{App} || $ENV{MT_APP}; |
|---|
| 42 | |
|---|
| 43 | if ($class) { |
|---|
| 44 | # When running under FastCGI, the initial invocation of the |
|---|
| 45 | # script has a bare environment. We can use this to test |
|---|
| 46 | # for FastCGI. |
|---|
| 47 | my $not_fast_cgi = 0; |
|---|
| 48 | $not_fast_cgi ||= exists $ENV{$_} |
|---|
| 49 | for qw(HTTP_HOST GATEWAY_INTERFACE SCRIPT_FILENAME SCRIPT_URL); |
|---|
| 50 | my $fast_cgi = defined $param{FastCGI} ? $param{FastCGI} : (!$not_fast_cgi); |
|---|
| 51 | if ($fast_cgi) { |
|---|
| 52 | eval 'require CGI::Fast;'; |
|---|
| 53 | $fast_cgi = 0 if $@; |
|---|
| 54 | } |
|---|
| 55 | |
|---|
| 56 | # ready to run now... run inside an eval block so we can gracefully |
|---|
| 57 | # die if something bad happens |
|---|
| 58 | my $app; |
|---|
| 59 | eval { |
|---|
| 60 | # line __LINE__ __FILE__ |
|---|
| 61 | require MT; |
|---|
| 62 | eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $class; 1;" or die $@; |
|---|
| 63 | if ($fast_cgi) { |
|---|
| 64 | $ENV{FAST_CGI} = 1; |
|---|
| 65 | while (my $cgi = new CGI::Fast) { |
|---|
| 66 | $app = $class->new( %param, CGIObject => $cgi ) |
|---|
| 67 | or die $class->errstr; |
|---|
| 68 | local $SIG{__WARN__} = sub { $app->trace($_[0]) }; |
|---|
| 69 | MT->set_instance($app); |
|---|
| 70 | $app->init_request(CGIObject => $cgi); |
|---|
| 71 | $app->run; |
|---|
| 72 | } |
|---|
| 73 | } else { |
|---|
| 74 | $app = $class->new( %param ) or die $class->errstr; |
|---|
| 75 | local $SIG{__WARN__} = sub { $app->trace($_[0]) }; |
|---|
| 76 | $app->run; |
|---|
| 77 | } |
|---|
| 78 | }; |
|---|
| 79 | if (my $err = $@) { |
|---|
| 80 | my $charset = 'utf-8'; |
|---|
| 81 | eval { |
|---|
| 82 | # line __LINE__ __FILE__ |
|---|
| 83 | my $cfg = MT::ConfigMgr->instance; #this is needed |
|---|
| 84 | $app ||= MT->instance; |
|---|
| 85 | my $c = $app->find_config; |
|---|
| 86 | $app->{cfg}->read_config($c); |
|---|
| 87 | $charset = $app->{cfg}->PublishCharset; |
|---|
| 88 | }; |
|---|
| 89 | if ($app && UNIVERSAL::isa($app, 'MT::App') && !UNIVERSAL::isa($app, 'MT::App::Wizard')) { |
|---|
| 90 | eval { |
|---|
| 91 | # line __LINE__ __FILE__ |
|---|
| 92 | my %param = ( error => $err ); |
|---|
| 93 | if ($err =~ m/Bad ObjectDriver/) { |
|---|
| 94 | $param{error_database_connection} = 1; |
|---|
| 95 | } elsif ($err =~ m/Bad CGIPath/) { |
|---|
| 96 | $param{error_cgi_path} = 1; |
|---|
| 97 | } elsif ($err =~ m/Missing configuration file/) { |
|---|
| 98 | $param{error_config_file} = 1; |
|---|
| 99 | } |
|---|
| 100 | my $page = $app->build_page('error.tmpl', \%param) |
|---|
| 101 | or die $app->errstr; |
|---|
| 102 | print "Content-Type: text/html; charset=$charset\n\n"; |
|---|
| 103 | print $page; |
|---|
| 104 | exit; |
|---|
| 105 | }; |
|---|
| 106 | $err = $@; |
|---|
| 107 | } else { |
|---|
| 108 | if ($err =~ m/Missing configuration file/) { |
|---|
| 109 | my $host = $ENV{SERVER_NAME} || $ENV{HTTP_HOST}; |
|---|
| 110 | $host =~ s/:\d+//; |
|---|
| 111 | my $port = $ENV{SERVER_PORT}; |
|---|
| 112 | my $uri = $ENV{REQUEST_URI} || $ENV{SCRIPT_NAME}; |
|---|
| 113 | if ($uri =~ m/(\/mt\.(f?cgi|f?pl)(\?.*)?)$/) { |
|---|
| 114 | my $script = $1; |
|---|
| 115 | my $ext = $2; |
|---|
| 116 | |
|---|
| 117 | if (-f File::Spec->catfile($ENV{MT_HOME}, "mt-wizard.$ext")) { |
|---|
| 118 | $uri =~ s/\Q$script\E//; |
|---|
| 119 | $uri .= '/mt-wizard.' . $ext; |
|---|
| 120 | |
|---|
| 121 | my $prot = $port == 443 ? 'https' : 'http'; |
|---|
| 122 | my $cgipath = "$prot://$host"; |
|---|
| 123 | $cgipath .= ":$port" |
|---|
| 124 | unless $port == 443 or $port == 80; |
|---|
| 125 | $cgipath .= $uri; |
|---|
| 126 | print "Status: 302 Moved\n"; |
|---|
| 127 | print "Location: " . $cgipath . "\n\n"; |
|---|
| 128 | exit; |
|---|
| 129 | } |
|---|
| 130 | } |
|---|
| 131 | } |
|---|
| 132 | print "Content-Type: text/plain; charset=$charset\n\n"; |
|---|
| 133 | print $app ? $app->translate("Got an error: [_1]", $app->translate($err)) : "Got an error: $err\n"; |
|---|
| 134 | } |
|---|
| 135 | } |
|---|
| 136 | } |
|---|
| 137 | } |
|---|
| 138 | |
|---|
| 139 | 1; |
|---|
| 140 | __END__ |
|---|
| 141 | |
|---|
| 142 | =head1 NAME |
|---|
| 143 | |
|---|
| 144 | MT::Bootstrap |
|---|
| 145 | |
|---|
| 146 | =head1 DESCRIPTION |
|---|
| 147 | |
|---|
| 148 | Startup module used to simplify MT application CGIs. |
|---|
| 149 | |
|---|
| 150 | =head1 SYNOPSIS |
|---|
| 151 | |
|---|
| 152 | Movable Type CGI scripts should utilize the C<MT::Bootstrap> module |
|---|
| 153 | to invoke the application code itself. When run, it is necessary |
|---|
| 154 | to add the MT "lib" directory to the Perl include path. |
|---|
| 155 | |
|---|
| 156 | Example (for CGIs in the main MT directory itself): |
|---|
| 157 | |
|---|
| 158 | #!/usr/bin/perl -w |
|---|
| 159 | use strict; |
|---|
| 160 | use lib $ENV{MT_HOME} ? "$ENV{MT_HOME}/lib" : 'lib'; |
|---|
| 161 | use MT::Bootstrap App => 'MT::App::CMS'; |
|---|
| 162 | |
|---|
| 163 | Example (for CGIs in a plugin subdirectory, ie MT/plugins/plugin_x): |
|---|
| 164 | |
|---|
| 165 | #!/usr/bin/perl -w |
|---|
| 166 | use strict; |
|---|
| 167 | use lib "lib", ($ENV{MT_HOME} ? "$ENV{MT_HOME}/lib" : "../../lib"); |
|---|
| 168 | use MT::Bootstrap App => 'MyApp'; |
|---|
| 169 | |
|---|
| 170 | =cut |
|---|