TypeKey
login_form_params => sub {
my ( $key, $blog_id, $entry_id, $static ) = @_;
my $entry = MT::Entry->load($entry_id) if $entry_id;
## TypeKey URL
require MT::Template::Context;
my $ctx = MT::Template::Context->new;
$ctx->stash( 'blog_id', $blog_id );
my $blog = MT::Blog->load($blog_id);
$ctx->stash( 'blog', $blog );
$ctx->stash( 'entry', $entry );
my $params = {};
$params->{tk_signin_url} =
MT::Template::Context::_hdlr_remote_sign_in_link( $ctx,
{ static => $static } );
return $params;
},
logo => 'images/comment/signin_typekey.png',
logo_small => 'images/comment/typekey_logo.png',
},
};
}
our %Captcha_Providers;
sub captcha_provider {
my $self = shift;
my ($key) = @_;
$self->init_captcha_providers() unless %Captcha_Providers;
return $Captcha_Providers{$key};
}
sub captcha_providers {
my $self = shift;
$self->init_captcha_providers() unless %Captcha_Providers;
my $def = delete $Captcha_Providers{'mt_default'};
my @vals = values %Captcha_Providers;
if ( defined($def) && $def->{condition}->() ) {
unshift @vals, $def;
}
@vals;
}
sub core_captcha_providers {
return {
'mt_default' => {
label => 'Movable Type default',
class => 'MT::Util::Captcha',
condition => sub {
require MT::Util::Captcha;
if ( my $error = MT::Util::Captcha->check_availability ) {
return 0;
}
1;
},
}
};
}
sub init_captcha_providers {
my $self = shift;
my $providers = $self->registry("captcha_providers") || {};
foreach my $provider ( keys %$providers ) {
delete $providers->{$provider}
if exists( $providers->{$provider}->{condition} )
&& !( $providers->{$provider}->{condition}->() );
}
%Captcha_Providers = %$providers;
$Captcha_Providers{$_}{key} ||= $_ for keys %Captcha_Providers;
}
sub effective_captcha_provider {
my $class = shift;
my ($key) = @_;
return undef unless $key;
my $cp = $class->captcha_provider($key) or return;
if ( exists $cp->{condition} ) {
return undef unless $cp->{condition}->();
}
my $pkg = $cp->{class};
$pkg =~ s/;//g;
eval "require $pkg" or return;
return $cp->{class};
}
sub handler_to_coderef {
my $pkg = shift;
my ( $name, $delayed ) = @_;
return $name if ref($name) eq 'CODE';
return undef unless defined $name && $name ne '';
my $code;
if ( $name !~ m/->/ ) {
# check for Package::Routine first; if defined, return coderef
no strict 'refs';
$code = \&$name if defined &$name;
return $code if $code;
}
my $component;
if ( $name =~ m!^\$! ) {
if ( $name =~ s/^\$(\w+)::// ) {
$component = $1;
}
}
if ( $name =~ m/^\s*sub\s*\{/s ) {
$code = eval $name or die $@;
if ($component) {
return sub {
my $mt_inst = MT->instance;
local $mt_inst->{component} = $component;
$code->(@_);
};
}
else {
return $code;
}
}
my $hdlr_pkg = $name;
my $method;
if ( $hdlr_pkg =~ s/(->|::)([^:]+)$// ) { # strip routine name
$method = $2 if $1 eq '->';
}
if ( !defined(&$name) && !UNIVERSAL::can( $hdlr_pkg, 'AUTOLOAD' ) ) {
# The delayed option will return a coderef that delays the loading
# of the package holding the handler routine.
if ($delayed) {
if ($method) {
return sub {
eval "require $hdlr_pkg;"
or Carp::confess(
"failed loading package $hdlr_pkg for routine $name: $@");
my $mt_inst = MT->instance;
local $mt_inst->{component} = $component
if $component;
return $hdlr_pkg->$method(@_);
};
}
else {
return sub {
eval "require $hdlr_pkg;"
or Carp::confess(
"failed loading package $hdlr_pkg for routine $name: $@");
my $mt_inst = MT->instance;
local $mt_inst->{component} = $component
if $component;
no strict 'refs';
my $hdlr = \&$name;
use strict 'refs';
return $hdlr->(@_);
};
}
}
else {
eval "require $hdlr_pkg;"
or Carp::confess(
"failed loading package $hdlr_pkg for routine $name: $@");
}
}
if ($method) {
$code = sub {
my $mt_inst = MT->instance;
local $mt_inst->{component} = $component
if $component;
return $hdlr_pkg->$method(@_);
};
}
else {
if ($component) {
$code = sub {
no strict 'refs';
my $hdlr = (
defined &$name ? \&$name
: ( UNIVERSAL::can( $hdlr_pkg, 'AUTOLOAD' ) ? \&$name
: undef )
);
use strict 'refs';
if ($hdlr) {
my $mt_inst = MT->instance;
local $mt_inst->{component} = $component
if $component;
return $hdlr->(@_);
}
return undef;
}
}
else {
no strict 'refs';
$code =
(
defined &$name
? \&$name
: ( UNIVERSAL::can( $hdlr_pkg, 'AUTOLOAD' ) ? \&$name : undef )
);
}
}
return $code;
}
1;
__END__
=head1 NAME
MT - Movable Type
=head1 SYNOPSIS
use MT;
my $mt = MT->new;
$mt->rebuild(BlogID => 1)
or die $mt->errstr;
=head1 DESCRIPTION
The I class is the main high-level rebuilding/pinging interface in the
Movable Type library. It handles all rebuilding operations. It does B
handle any of the application functionality--for that, look to I and
I, both of which subclass I to handle application requests.
=head1 PLUGIN APPLICATIONS
At any given time, the user of the Movable Type platform is
interacting with either the core Movable Type application, or a plugin
application (or "sub-application").
A plugin application is a plugin with a user interface that inherits
functionality from Movable Type, and appears to the user as a
component of Movable Type. A plugin application typically has its own
templates displaying its own special features; but it inherits some
templates from Movable Type, such as the navigation chrome and error
pages.
=head2 The MT Root and the Application Root
To locate assets of the core Movable Type application and any plugin
applications, the platform uses two directory paths, C and
C. These paths are returned by the MT class methods with the
same names, and some other methods return derivatives of these paths.
Conceptually, mt_dir is the root of the Movable Type installation, and
app_dir is the root of the "currently running application", which
might be Movable Type or a plugin application. It is important to
understand the distinction between these two values and what each is
used for.
The I is the absolute path to the directory where MT itself is
located. Most importantly, the MT configuration file and the CGI scripts that
bootstrap an MT request are found here. This directory is also the
default base path under which MT's core templates are found (but this
can be overridden using the I configuration setting).
Likewise, the I is the directory where the "current"
application's assets are rooted. The platform will search for
application templates underneath the I, but this search also
searches underneath the I, allowing the application to make
use of core headers, footers, error pages, and possibly other
templates.
In order for this to be useful, the plugin's templates and
code should all be located underneath the same directory. The relative
path from the I to the application's templates is
configurable. For details on how to indicate the location of your
plugin's templates, see L.
=head2 Finding the Root Paths
When a plugin application initializes its own application class (a
subclass of MT::App), the I should be discovered and passed
constructor. This comes either from the C parameter or the
C parameter.
Since plugins are loaded from a descendent of the MT root directory,
the plugin bootstrap code can discover the MT configuration file (and thus
the MT root directory) by traversing the filesystem; the absolute path
to that file can be passed as the C parameter to
MT::App::new. Working code to do this can be found in the
examples/plugins/mirror/mt-mirror.cgi file.
The I, on the other hand, always derives from the location of
the currently-running program, so it typically does not need to be
specified.
=head1 USAGE
I has the following interface. On failure, all methods return C
and set the I for the object or class (depending on whether the
method is an object or class method, respectively); look below at the section
L for more information.
=head2 MT->new( %args )
Constructs a new I instance and returns that object. Returns C
on failure.
I will also read your MT configuration file (provided that it can find it--if
you find that it can't, take a look at the I directive, below). It
will also initialize the chosen object driver; the default is the C
object driver.
I<%args> can contain:
=over 4
=item * Config
Path to the MT configuration file.
If you do not specify a path, I will try to find your MT configuration file
in the current working directory.
=item * Directory
Path to the MT home directory.
If you do not specify a path, I will try to find the MT directory using
the discovered path of the MT configuration file.
=back
=head2 $mt->init
Initializes the Movable Type instance, including registration of basic
resources and callbacks. This method also invokes the C
and C methods.
=head2 MT->instance
MT and all it's subclasses are now singleton classes, meaning you can only
have one instance per package. MT->instance() returns the active instance.
MT->new() is now an alias to instance_of.
=head2 $class->instance_of
Returns the singleton instance of the MT subclass identified by C<$class>.
=head2 $class->construct
Constructs a new instance of the MT subclass identified by C<$class>.
=head2 MT->set_instance
Assigns the active MT instance object. This value is returned when
Cinstance> is invoked.
=head2 $mt->find_config($params)
Handles the discovery of the MT configuration file. The path and filename
for the configuration file is returned as the result. The C<$params>
parameter is a reference to the hash of settings passed to the MT
constructor.
=head2 $mt->init_config($params)
Reads the MT configuration settingss from the MT configuration file
and settings from database (L).
The C<$params> parameter is a reference to the hash of settings passed to
the MT constructor.
=head2 $mt->init_plugins
Loads any discoverable plugins that are available. This is called from
the C method, after the C method has loaded the
configuration settings.
=head2 $mt->init_tasks
Registers the standard set of periodic tasks that Movable Type provides
and then invokes the C method for each available plugin.
=head2 MT->add_task
An alias for Ladd_task>. Refer to the L
documentation for more information.
=head2 MT->run_tasks
Initializes the tasks, running C and invokes the task system
through L to run any registered tasks that are pending
execution. See L for further documentation.
=head2 MT->unplug
Removes the global reference to the MT instance.
=head2 MT::log( $message ) or $mt->log( $message )
Adds an entry to the application's log table. Also writes message to
STDERR which is typically routed to the web server's error log.
=head2 $mt->server_path, $mt->mt_dir
Both of these methods return the physical file path to the directory
that is the home of the MT installation. This would be the value of
the 'Directory' parameter given in the MT constructor, or would be
determined based on the path of the configuration file.
=head2 $mt->app_dir
Returns the physical file path to the active application directory. This
is determined by the directory of the active script.
=head2 $mt->config_dir
Returns the path to the MT configuration file.
=head2 $mt->config([$setting[, $value]])
This method is used to get and set configuration settings. When called
without any parameters, it returns the active MT::ConfigMgr instance
used by the application.
Specifying the C<$setting> parameter will return the value for that setting.
When passing the C<$value> parameter, this will update the config object,
assigning that value for the named C<$setting>.
=head2 $mt->user_class
Returns the package name for the class used for user authentication.
This is typically L.
=head2 $mt->request([$element[,$data]])
The request method provides a request-scoped storage object. It is an
access interface for the L package. Calling without any
parameters will return the L instance.
When called with the C<$element> parameter, the data stored for that
element is returned (or undef, if it didn't exist). When called with
the C<$data> parameter, it will store the data into the specified
element in the request object.
All values placed in the request object are lost at the end of the
request. If the running application is not a web-based application,
the request object exists for the lifetime of the process and is
released when the process ends.
See the L package for more information.
=head2 MT->new_ua
Returns a new L instance that is configured according to the
Movable Type configuration settings (specifically C, C, C and C). The agent string is set
to "MovableType/(version)" and is also limited to receiving a response of
100,000 bytes by default (you can override this by using the 'max_size'
method on the returned instance). Using this method is recommended for
any HTTP requests issued by Movable Type since it uses the MT configuration
settings to prepare the UserAgent object.
=head2 $mt->ping( %args )
Sends all configured XML-RPC pings as a way of notifying other community
sites that your blog has been updated.
I<%args> can contain:
=over 4
=item * Blog
An I object corresponding to the blog for which you would like to
send the pings.
Either this or C is required.
=item * BlogID
The ID of the blog for which you would like to send the pings.
Either this or C is required.
=back
=head2 $mt->ping_and_save( %args )
Handles the task of issuing any pending ping operations for a given
entry and then saving that entry back to the database.
The I<%args> hash should contain an element named C that is a
reference to a L object.
=head2 $mt->needs_ping(%param)
Returns a list of URLs that have not been pinged for a given entry. Named
parameters for this method are:
=over 4
=item Entry
The L object to examine.
=item Blog
The L object that is the parent of the entry given.
=back
The return value is an array reference of URLs that have not been pinged
for the given entry.
An empty list is returned for entries that have a non 'RELEASE' status.
=head2 $mt->update_ping_list($blog)
Returns a list of URLs for ping services that have been configured to
be notified when posting new entries.
=head2 $mt->set_language($tag)
Loads the localization plugin for the language specified by I<$tag>, which
should be a valid and supported language tag--see I to
obtain a list of supported languages.
The language is set on a global level, and affects error messages and all
text in the administration system.
This method can be called as either a class method or an object method; in
other words,
MT->set_language($tag)
will also work. However, the setting will still be global--it will not be
specified to the I<$mt> object.
The default setting--set when I is called--is U.S. English. If a
I is set in the MT configuration file, the default is then
set to that language.
=head2 MT->translate($str[, $param, ...])
Translates I<$str> into the currently-set language (set by I),
and returns the translated string. Any parameters following I<$str> are
passed through to the C method of the active localization module.
=head2 MT->translate_templatized($str)
Translates a string that has embedded EMT_TRANSE tags. These
tags identify the portions of the string that require localization.
Each tag is processed separately and passed through the MT->translate
method. Examples (used in your application's HTML::Template templates):
and
=head2 $mt->trans_error( $str[, $arg1, $arg2] )
Translates I<$str> into the currently-set language (set by I),
and assigns it as the active error for the MT instance. It returns undef,
which is the usual return value upon generating an error in the application.
So when an error occurs, the typical return result would be:
if ($@) {
return $app->trans_error("An error occurred: [_1]", $@);
}
The optional I<$arg1> (and so forth) parameters are passed as parameters to
any parameterized error message.
=head2 $mt->current_language
Returns the language tag for the currently-set language.
=head2 MT->supported_languages
Returns a reference to an associative array mapping language tags to their
proper names. For example:
use MT;
my $langs = MT->supported_languages;
print map { $_ . " => " . $langs->{$_} . "\n" } keys %$langs;
=head2 MT->language_handle
Returns the active MT::L10N language instance for the active language.
=head2 MT->add_plugin($plugin)
Adds the plugin described by $plugin to the list of plugins displayed
on the welcome page. The argument should be an object of the
I class.
=head2 MT->add_plugin_action($where, $action_link, $link_text)
An alias to the active L instance C method.
Please refer to the L module for further documentation.
=head2 MT->add_itemset_action(\%options)
An alias to the active L instance C method.
Please refer to the L module for further documentation.
=head2 MT->add_text_filter($key, \%options)
Adds a text filter with the short name I<$key> and the options in
I<\%options>.
The text filter will be added to MT's list of text filtering options in
the new/edit entry screen, and will be used for filtering all of the entry
fields, if the user has enabled filtering for those fields in the template
(for example, by default the entry body and extended text are both run
through the filter, but the excerpt is not).
I<$key> should be a lower-case identifier containing only
alphanumerics and C<_> (that is, matching C\w+/>). Since I<$key> is
stored as the filter name on a per-entry basis, it B.
(In other words, don't call if I in one version and I in
the next, if the filter does the same thing in each version.)
The flip side of this, though, is that if your filter acts differently
from one version to the next, you B change I<$key>, and you
should also change the filename of your plugin, so that the old
implementation--which may be associated with all of the entries in the user's
system--still works as usual. For example, if your C plugin changes
semantics drastically so that paragraph breaks are represented as two
Cbr /E> tags, rather than CpE> tags, you should change
the key of the new version to C (for example), and the filename to
F.
I<%options> can contain:
=over 4
=item * label
The short-but-descriptive label for the filter. This will be displayed in
the Movable Type UI as the name of the text filter.
=item * on_format
A reference to a subroutine that will be executed to filter a string of
text. The subroutine will always receive one argument, the string of text to
filter, and should return the filtered string. In some cases--for example,
when called while building a template--the subroutine will receive a
second argument, the I object handling the build.
See the example below.
=item * docs
The URL (or filename) of a document containing documentation on your filter.
This will be displayed in a popup window when the user selects your filter
on the New/Edit Entry screen, then clicks the Help link (C<(?)>).
If the value is a full URL (starting with C), the popup window
will open with that URL; otherwise, it is treated as a filename, assumed to
be in the user's F folder.
=back
Here's an example of adding a text filter for Wiki formatting, using the
I CPAN module:
MT->add_text_filter(wiki => {
label => 'Wiki',
on_format => sub {
require Text::WikiFormat;
Text::WikiFormat::format($_[0]);
},
docs => 'http://www.foo.com/mt/wiki.html',
});
=head2 MT->all_text_filters
Returns a reference to a hash containing the registry of text filters.
=head2 MT->apply_text_filters($str, \@filters)
Applies the set of filters I<\@filters> to the string I<$str> and returns
the result (the filtered string).
I<\@filters> should be a reference to an array of filter keynames--these
are the short names passed in as the first argument to I.
I<$str> should be a scalar string to be filtered.
If one of the filters listed in I<\@filters> is not found in the list of
registered filters (that is, filters added through I),
it will be skipped silently. Filters are executed in the order in which they
appear in I<\@filters>.
As it turns out, the I method returns a reference
to the list of text filters to be used for that entry. So, for example, to
use this method to apply filters to the main entry text for an entry
I<$entry>, you would use
my $out = MT->apply_text_filters($entry->text, $entry->text_filters);
=head2 MT->add_log_class($class)
Registers a new L subclass with MT, which is used for presenting
specific types of log records in the activity log and activity feeds. See
L for further documentation on custom log classes.
=head2 MT->add_callback($meth, $priority, $plugin, $code)
Registers a new callback handler for a particular registered callback.
The first parameter is the name of the callback method. The second
parameter is a priority (a number in the range of 1-10) which will control
the order that the handler is executed in relation to other handlers. If
two handlers register with the same priority, they will be executed in
the order that they registered. The third parameter is a C object
reference that is associated with the handler (this parameter is optional).
The fourth parameter is a code reference that is invoked to handle the
callback. For example:
MT->add_callback('BuildFile', 1, undef, \&rebuild_file_hdlr);
The code reference should expect to receive an object of type
L as its first argument. This object is used to
communicate errors to the caller:
sub rebuild_file_hdlr {
my ($cb, ...) = @_;
if (something bad happens) {
return $cb->error("Something bad happened!");
}
}
Other parameters to the callback function depend on the callback point.
The treatment of the error string depends on the callback point.
Typically, either it is ignored or the user's action fails and the
error message is displayed.
The value returned from this method is the new L object.
=head2 MT->remove_callback($callback)
Removes a callback that was previously registered.
=head2 MT->register_callbacks([...])
Registers several callbacks simultaneously. Each element in the array
parameter given should be a hashref containing these elements: C,
C, C and C.
=head2 MT->run_callbacks($meth[, $arg1, $arg2, ...])
Invokes a particular callback, running any associated callback handlers.
The first parameter is the name of the callback to execute. This is one
of the global callback methods (see L section) or can be
a class-specific method that includes the package name associated with
the callback.
The remaining arguments are passed through to any callback handlers that
are invoked.
For "Filter"-type callbacks, this routine will return a 0 if any of the
handlers return a false result. If all handlers return a true result,
a value of 1 is returned.
Example:
MT->run_callbacks('MyClass::frobnitzes', \@whirlygigs);
Which would execute any handlers that registered in this fashion:
MT->add_callback('MyClass::frobnitzes', 4, $plugin, \&frobnitz_hdlr);
=head2 MT->register_junk_filter( $filter )
Registers a new L with Movable Type. Junk filters are
used to identify spam for incoming feedback. Please see documentation
for L for more information.
Example:
require MT::JunkFilter;
MT->register_junk_filter(new MT::JunkFilter({
name => "My Junk Filter",
code => sub { $plugin->my_junk_filter(@_) },
plugin => $plugin,
}));
=head2 MT->run_callback($cb[, $arg1, $arg2, ...])
An internal routine used by C to invoke a single
L.
=head2 callback_error($str)
This routine is used internally by C to set any error response
that comes from invoking a callback.
=head2 callback_errstr
This internal routine returns the error response stored using the
C routine.
=head2 MT->product_code
The product code identifying the Movable Type product that is installed.
This is either 'MTE' for Movable Type Enterprise or 'MT' for the
non-Enterprise product.
=head2 MT->product_name
The name of the Movable Type product that is installed. This is either
'Movable Type Enterprise' or 'Movable Type Publishing Platform'.
=head2 MT->product_version
The version number of the product. This is different from the C
and C methods as they report the API version information.
=head2 MT->version_id
Returns the API version of MT (including any beta/alpha designations).
=head2 MT->version_number
Returns the numeric API version of MT (without any beta/alpha designations).
For example, if I returned C<2.5b1>, I would
return C<2.5>.
=head2 MT->schema_version
Returns the version of the MT database schema.
=head2 MT->version_slug
Returns a string of text that is appended to emails sent through the
C method.
=head2 $mt->publisher
Returns the L object that is used for managing the
MT publishing process. See L for more information.
=head2 $mt->rebuild
An alias to L. See L
for documentation of this method.
=head2 $mt->rebuild_entry
An alias to L. See L
for documentation of this method.
=head2 $mt->rebuild_indexes
An alias to L. See
L for documentation of this method.
=head2 $mt->build_email($file, $param)
Loads a template from the application's 'email' template directory and
processes it as a HTML::Template. The C<$param> argument is a hash reference
of parameter data for the template. The return value is the output of the
template.
=head2 MT::get_next_sched_post_for_user($author_id, @blog_ids)
This is an internal routine used by L and the
getNextScheduled XMLRPC method to determine the timestamp for the next
entry that is scheduled for publishing. The return value is the timestamp
in UTC time in the format "YYYY-MM-DDTHH:MM:SSZ".
=head1 ERROR HANDLING
On an error, all of the above methods return C, and the error message
can be obtained by calling the method I on the class or the object
(depending on whether the method called was a class method or an instance
method).
For example, called on a class name:
my $mt = MT->new or die MT->errstr;
Or, called on an object:
$mt->rebuild(BlogID => $blog_id)
or die $mt->errstr;
=head1 DEBUGGING
MT has a package variable C<$MT::DebugMode> which is assigned through
your MT configuration file (DebugMode setting). If this is set to
any non-zero value, MT applications will display any C'd
statements to a panel that is displayed within the app.
The DebugMode is a bit-wise setting and offers the following options:
1 - Display debug messages
2 - Display a stack trace for messages captured
4 - Lists queries issued by Data::ObjectDriver
8 - Reports on MT templates that take more than 1/4 second to build*
128 - Outputs app-level request/response information to STDERR.
These can be combined, so if you want to display queries and debug messages,
use a DebugMode of 5 for instance.
You may also use the local statement to temporarily apply a particular bit,
if you want to scope the debug messages you receive to a block of code:
local $MT::DebugMode |= 4; # show me the queries for the following
my $obj = MT::Entry->load({....});
*DebugMode bit 8 actually outputs it's messages to STDERR (which typically
is sent to your web server's error log).
=head1 CALLBACKS
Movable Type has a variety of hook points at which a plugin can attach
a callback.
In each case, the first parameter is an L object which
can be used to pass error information back to the caller.
The app-level callbacks related to rebuilding are documented
in L. The specific apps document the callbacks
which they invoke.
=head2 NewUserProvisioning($cb, $user)
This callback is invoked when a user is being added to Movable Type.
Movable Type itself registers for this callback (with a priority of 5)
to provision the user with a new weblog if the system has been configured
to do so.
=head1 LICENSE
The license that applies is the one you agreed to when downloading
Movable Type.
=head1 AUTHOR & COPYRIGHT
Except where otherwise noted, MT is Copyright 2001-2007 Six Apart.
All rights reserved.
=cut