Gossamer Forum
Home : Products : Gossamer Links : Development, Plugins and Globals :

Calling cgi function from plugin.PM file

Quote Reply
Calling cgi function from plugin.PM file
Is it possible to call a function in a cgi script from a plugin's PM file?

Example...
File: plugin.cgi
Code:
sub some_function {

my $args = $IN->get_hash;

}

Then from MyPlugin.pm can I call some_function() and pass arguments?

File: MyPlugin.PM
Code:
sub wrapper_function {

some_function(arg1, arg2, etc);

}

Eventually to use in a template like:
<%
Plugins::
MyPlugin::wrapper_function($arg1, $arg2, $etc)%>

???

Currently I have resorted to making a local copy of the cgi subroutine
in the .PM file, but it seems seems redundent to me me. :-)

Thanks for any help.
Chris



RGB World, Inc. - Software &amp; Web Development.
rgbworld.com
Quote Reply
Re: [rgbworld] Calling cgi function from plugin.PM file In reply to
I think you are going about this all wrong.

If you look at the .cgi scripts that users call, they are about 10 lines, mainly set up code, environment checks (for mod_perl) and then a call to the plugin/handler routines. This was changed in the 2.x release, and it makes a lot more sense.

You can get a lot of ideas how to set this up by looking at add.pm, modify.pm, search.pm, etc.

What you should do, is have all, and I mean _ALL_ of the .cgi programs follow the same skelleton, and load a .pm file to do all the work.

This should solve the problem you are asking about, as well as make sure you follow the rules as it were to have programs that properly set up and exit for mod_perl compatibility.

If all your "work" is done in the modules, you can access and load modules following normal perl conventions, and it makes debugging and program flow much more logical. You also never have to update your .cgi files, only the .pm files, which makes keeping things in order (unix permissions, etc) easier too.


PUGDOG� Enterprises, Inc.

The best way to contact me is to NOT use Email.
Please leave a PM here.
Quote Reply
Re: [pugdog] Calling cgi function from plugin.PM file In reply to
Great. I understand, and you're correct it should solve my problem.

But just to clarify :-)
The .cgi file is just a router and everything goes in the .PM file correct?

Question:
Code:
use strict;
...
use Plugins::MyPlugin; # Do I need a special 'use' ?

local $SIG{__DIE__} = \&Links::fatal; # What is this doing?
...

if ($PLG->dispatch('check_request', \&Plugins::MyPlugin::check_request)) {
$PLG->dispatch('handle_plugin', \&Plugins::MyPlugin::handle);
}
I am sure I can figure it out once I get to it.

Thanks
Chris
RGB World, Inc. - Software &amp; Web Development.
rgbworld.com
Quote Reply
Re: [rgbworld] Calling cgi function from plugin.PM file In reply to
You'll likely need to do a "use lib..." in your script.

Links::fatal is an error handler. If the script/module dies you'll get a pretty error page instead of 500 ISE.

"check_request" (which should remain as &Links::check_request, unless you want to everride the function) checks that the IP/referer of the current user isn't banned before allowing the requested action to run. If you have your set as 'disabled' in the admin, than any accesses from a .cgi will return an error page.

"handle_request" is simply the subroutine that takes the input parameters and sends it off to the appropriate function.

you don't *have* to use any of them. You could get by with just:

Code:
#!/usr/bin/perl
use strict;
use lib 'path/to/admin';
use Plugins::MyPlugin;

Plugins::MyPlugin::main();

Of course, NOT using them means that if other plugins run hooks on 'check_request' or 'handle_request', their code will not run. And you'll need to handle bans,etc. on your own.

Philip
------------------
Limecat is not pleased.
Quote Reply
Re: [rgbworld] Calling cgi function from plugin.PM file In reply to
Yes, *everything* goes in the .pm file, except the few lines of init code. Object creation and such is also moved to the .pm file. This is a change for GL3 somewhat.

From jump.cgi (my favorite file to play with since 2.0)
=============

use strict;
use lib '/path/toadmin'; ## this gets set to your admin path
use Links qw/$PLG/;
use Links::User::Jump; ## this is the name of your .pm file, Plugins::MyPlugin for example.
local $SIG{__DIE__} = \&Links::fatal;
Links::init('/path/to/admin'); ## again, your admin path
Links::init_user();
if ($PLG->dispatch('check_request', \&Links::check_request)) { ## this is left alone, it does housekeeping
$PLG->dispatch('handle_jump', \&Links::User::Jump::handle); ## this you need tomodify
}
===============================

handle_jump is the plugin hook to run, and if you don't have a plugin hook, you can actually make something up, since it's only a "check" it won't cause an error. Just don't make it an existing hook, or you'll get weird errors. Calling it handle_pluginname is usually ok.

The code in red is what you need to change. If your module is located at Plugins::MyModule and the "main" routine you want to run, your "handler" as it were was called "handle" (by convention for the plugins), you would use Plugins::MyPlugin::handle as the routine to run. That switches the processing from your .cgi to the .pm file, and you can see how the .pm files are set up by looking at the ones that come with the GT software.

Note: This is a *major* change in setup from earlier systems, as most of the houskeeping code has been objectified, and in the GL3 release, the use Links is now use Links qw/:objects/ which handles the set up and export of the proper objects -- $DB, $IN, $CGI, etc.


PUGDOG� Enterprises, Inc.

The best way to contact me is to NOT use Email.
Please leave a PM here.
Quote Reply
Re: [pugdog] Calling cgi function from plugin.PM file In reply to
Ok well I got it, but for a while I 'thought' I wasn't doing something right Crazy

In ZipCodeSearch.pm, I have
Code:
use strict;
use lib '';
use Links qw/$PLG/;
use Plugins::ZipCodeSearch;

local $SIG{__DIE__} = \&Links::fatal;

Links::init();
Links::init_user();

if ($PLG->dispatch('check_request', \&Links::check_request)) {
$PLG->dispatch('handle_ZipCodeSearch', \&Plugins::ZipCodeSearch::handle);
}


And I get this error when running 'perl check' on the module.
Quote:
Empty compile time value given to use lib at zipcode_search.cgi line 13
Can't locate Plugins/ZipCodeSearch.pm in @INC (@INC contains:
/home/virtual/site129/fst/var/www/cgi-bin/links_dev/admin /usr/lib/perl5/5.8.0/i386-linux-thread-multi
/usr/lib/perl5/5.8.0 /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.0 /usr/lib/perl5/site_perl
/usr/lib/perl5/vendor_perl/5.8.0/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.0 /usr/lib/perl5/vendor_perl .) at zipcode_search.cgi line 14.
BEGIN failed--compilation aborted at zipcode_search.cgi line 14.

Line 13 is use lib'';
I am doing proper substitutions in Install.pm for the 'path/to/admin' for use lib and Links::init().

Of course when running the perl check it can't find the PM file, because it isn't installed yet.
And the "Empty compile Time" error I have always ignored too.

For completeness, in ZipCodeSearch.pm, I have
Code:
package Plugins::ZipCodeSearch;
# ==================================================================

use strict;
use GT::Base;
use GT::Plugins qw/STOP CONTINUE/;
use Links qw/:objects/;
use Links::Plugins;
use GT::Config;
use Links::Tools;
use Plugins::ZipCodeSearch;

# Inherit from base class for debug and error methods
@Plugins::ZipCodeSearch::ISA = qw(GT::Base);

# Your code begins here.

my $pi = atan2(1,1) * 4;
my $time_hires;

sub handle {
#--------------------------------------------------------------------------------
#
my $args = $IN->get_hash;
...
}


So am I just suppossed to ignore the compile error when doing 'perl check'?
Sorry guys, I am trying to get it right.

What do these 2 lines do?
Code:
use CGI::Carp qw(fatalsToBrowser);

@Plugins::ZipCodeSearch::ISA = qw(GT::Base);


With that I should have a complete understanding.

Thanks
Chris
RGB World, Inc. - Software &amp; Web Development.
rgbworld.com

Last edited by:

rgbworld: Jul 30, 2006, 12:07 AM
Quote Reply
Re: [rgbworld] Calling cgi function from plugin.PM file In reply to
Code:
use lib '';

should be the full path to your admin directory.

Code:
use CGI::Carp qw(fatalsToBrowser);

is similar to the Links::fatal() call used inthe .cgi scripts. it (usually) will give you an nice HTML formatted error message instead of a 500 internal server error, if your script doesn't compile.

Code:
@Plugins::ZipCodeSearch::ISA = qw(GT::Base);

Inheritance. IIRC, this is for error handling.

Philip
------------------
Limecat is not pleased.
Quote Reply
Re: [fuzzy logic] Calling cgi function from plugin.PM file In reply to
In Reply To:


Code
use lib '';[/code]should be the full path to your admin directory.[/quote]I understand that, but the quotes are empty, and the empty quotes get replaced with the users path/to/admin
when the plugin gets installed. So when I do a 'perl check' on the code (uninstalled), it gives the "Empty Compile Time" error
shown in prev post. It works fine after installed.

Do I just ignore the "Empty Compile Time" as I always have?
Also ignore the "Can't locate Plugin.pm - Compile aborted" error?

Again these errors do not appear AFTER I install the plugin, they
only appear when I am doing a 'perl check' on the code.

Thanks for all the excellent explainations. I do understand, and it all works
thanks to you guru's Wink

Chris

RGB World, Inc. - Software &amp; Web Development.
rgbworld.com
Quote Reply
Re: [rgbworld] Calling cgi function from plugin.PM file In reply to
Sorry, didn't see that. I get the same errors. They only occur during checks, but they are very annoying. I resorted to having a 'use lib" at the top of my plugin so I can run a "perl -c" on the plugin module while I debug.

Philip
------------------
Limecat is not pleased.