# Copyright 2002-2008 Josh Clark and Global Moxie, LLC. This code cannot be 
# redistributed without permission from globalmoxie.com.  For more
# information, consult your Big Medium license.
#
# $Id: Plugin.pm 3043 2008-03-31 14:00:38Z josh $

package BigMed::Plugin;
use Carp;
$Carp::Verbose = 1;
use BigMed;
use BigMed::DiskUtil qw(bm_file_path bm_untaint_filepath);
use strict;
use utf8;

#default values: can be module style or path style
my @content_classes = (
    'BigMed::Content::Page',
    'BigMed::Content::Tip',
    'BigMed::Content::Annc',
);
my @media_classes = (
    'BigMed::Media::Image',
    'BigMed::Media::Document',
    'BigMed::Media::AV',
);
my @library_classes = (
    @media_classes,
    'BigMed::Person',
);
my @content_filters = (
    'BigMed::Filter::WYSIWYG',
    'BigMed::Filter::Markdown',
);
my @formats = (
    'BigMed::Format::HTML',
    'BigMed::Format::RSS',
    'BigMed::Format::JS',
    'BigMed::Format::Sitemap',
);


sub init_plugins { #load plugins
    my $class = shift;
    my $moxiebin_dir;
    if ($0 =~ m!(.*)[/\\]!) {
        $moxiebin_dir = $1;
    } else {
        $moxiebin_dir = '.';
    }
    my $plugin_dir = bm_file_path($moxiebin_dir, 'plugins');
    return if !-e $plugin_dir;

    unshift @INC,  bm_file_path($plugin_dir, 'modules');
    unshift @INC, $plugin_dir;
    my ($DIR, $plugin);
    opendir($DIR, $plugin_dir)
      or croak "Cannot open plugin directory $plugin_dir: $!";
    while (defined($plugin = readdir($DIR))) {
        next if substr($plugin, -3) ne '.pl';
        $plugin = bm_untaint_filepath($plugin)
          or croak "Could not untaint path to plugin: $plugin_dir/$plugin";
        require $plugin;
    }
    closedir($DIR);
}

sub add_content_filter {
    push @content_filters, $_[1];
}

sub add_format {
    push @formats, $_[1];
}

sub add_media {
    push @media_classes, $_[1];
    push @library_classes, $_[1];
}

sub add_library {
    push @library_classes, $_[1];
}

sub add_content {
    push @content_classes, $_[1];
}

#loader methods... these should be lazy loaded and requested only when you
#need them

sub load_content_types {
    do_load(@content_classes);
    return BigMed::Content->content_classes();
}

sub load_media_types {
    do_load(@media_classes);
    return BigMed::Media->media_classes();
}

sub load_library_types {
    do_load(@library_classes);
    return BigMed::Library->library_classes();
}

sub load_content_filters {
    do_load(@content_filters);
}

sub load_formats {
    do_load(@formats);
    return BigMed::Format->format_classes();
}

sub do_load {
    foreach my $class (@_) {
        BigMed->load_required_class($class);
    }
    @_;
}

1;

__END__


=head1 BigMed::Plugin

Registers and manages plug-in modules for modifying the behavior of the
Big Medium content management system

=head1 Description

Big Medium includes a plug-in architecture that allows developers to add
custom behaviors and features to the CMS.

These plugin scripts are executed during the initialization of the
BigMed::App object. The scripts must have a .pl filename suffix and should
be placed in the moxiebin/plugins directory.

=head1 Synopsis

=head1 The Plug-In Instance Script

=head1 Methods

=head2 Adding plug-in behaviors

=head3 C<add_format>

    BigMed::Plugin->add_format($module_name);

Adds the module to the queue of modules to be loaded when BigMed::Format
subclasses are required.

=head3 C<add_content>

    BigMed::Plugin->add_content($module_name);

Adds the module to the queue of modules to be loaded when BigMed::Content
subclasses are required.

=head3 C<add_library>

    BigMed::Plugin->add_library($module_name);

Adds the module to the queue of modules to be loaded when BigMed::Library
subclasses are required.

=head3 C<add_media>

    BigMed::Plugin->add_media($module_name);

Adds the module to the queue of modules to be loaded when BigMed::Media
subclasses are required (this automatically adds items to the
C<add_library> queue, too).

=head3 C<add_content_filter>

    BigMed::Plugin->add_content_filter($module_name);

Adds the module to the queue of modules to be loaded when text filters
are required.

=head2 Activating the plug-ins

=head3 C<< BigMed::Plugin->init_plugins() >>

Typically called just once by the BigMed::App object at construction.
Loads all of the plug-in instance scripts from the moxiebin plugins
directory. Also adds the plugins/modules directory as the first
element of @ISA so that custom modules and libraries can be reliably
loaded from a known location.

=head2 Accessing plug-in values and behaviors

=head3 C<< BigMed::Plugin->load_content_classes() >>

Loads the registered content classes/modules. Returns the array
of content classes after all modules are loaded.

=head3 C<< BigMed::Plugin->load_library_types() >>

Loads the registered library classes/modules. Returns the array
of library classes after all modules are loaded.

=head3 C<< BigMed::Plugin->load_media_types() >>

Loads the registered media classes/modules. Returns the array
of media classes after all modules are loaded.

=head3 C<< BigMed::Plugin->load_formats() >>

Loads the registered BigMed::Format formats. Returns the array
of class names registered via C<add_format>.

=head3 C<< BigMed::Plugin->load_content_filters() >>

Loads the registered media classe/modules. Returns the array
of class names registered via C<add_content_filter>.

=head1 AUTHOR & COPYRIGHTS

This module and all Big Medium modules are copyright Josh Clark
and Global Moxie. All rights reserved.

Use of this module and the Big Medium content
management system are governed by Global Moxie's software licenses
and may not be used outside of the terms and conditions outlined
there.

For more information, visit the Global Moxie website at
L<http://globalmoxie.com/>.

Big Medium and Global Moxie are service marks of Global Moxie
and Josh Clark. All rights reserved.

=cut
