-package FS::XMLRPC;
+ package FS::XMLRPC;
use strict;
-use vars qw( @ISA $DEBUG );
+use vars qw( $DEBUG );
use Frontier::RPC2;
-use FS::Record qw( qsearch qsearchs );
-use FS::cust_main qw( smart_search );
-@ISA = qw( );
+# Instead of 'use'ing freeside modules on the fly below, just preload them now.
+use FS;
+use FS::CGI;
+use FS::Conf;
+use FS::Record;
+use FS::cust_main;
-$DEBUG = 1;
+use Data::Dumper;
+
+$DEBUG = 0;
=head1 NAME
my ($method_name, $params) = (shift, shift);
- use Data::Dumper;
#die 'Called _serve without parameters' unless ref($params) eq 'ARRAY';
$params = [] unless (ref($params) eq 'ARRAY');
- my ($class, $sub) = split(/\./, $method_name);
- my $fssub = "FS::${class}::${sub}";
- warn "fssub: ${fssub}" if $DEBUG;
- warn "params: " . Dumper($params) if $DEBUG;
-
- unless (UNIVERSAL::can("FS::${class}", $sub)) {
- warn "FS::XMLRPC: Can't call undefined subroutine '${fssub}'";
- # Should we encode an error in the response,
- # or just break silently to the remote caller and complain locally?
- return [];
- }
-
- my @result;
- eval {
- no strict 'refs';
+ if ($method_name =~ /^(\w+)\.(\w+)/) {
+
+ #my ($class, $sub) = split(/\./, $method_name);
+ my ($class, $sub) = ($1, $2);
my $fssub = "FS::${class}::${sub}";
- @result = (&$fssub(@$params));
- };
-
- if ($@) {
- warn "FS::XMLRPC: Error while calling '${fssub}': $@";
- return [];
- }
-
- warn Dumper(@result);
-
- if (grep { UNIVERSAL::can($_, 'hashref') ? 0 : 1 } @result) {
- warn "FS::XMLRPC: One or more objects returned from '${fssub}' doesn't " .
- "support the 'hashref' method.";
- return [];
- } else {
- return [ map { $_->hashref } @result ];
- }
+ warn "fssub: ${fssub}" if $DEBUG;
+ warn "params: " . Dumper($params) if $DEBUG;
+
+ my @result;
+
+ if ($class eq 'Conf') { #Special case for FS::Conf because we need an obj.
+
+ if ($sub eq 'config') {
+ my $conf = new FS::Conf;
+ @result = ($conf->config(@$params));
+ } else {
+ warn "FS::XMLRPC: Can't call undefined subroutine '${fssub}'";
+ }
+
+ } else {
+
+ unless (UNIVERSAL::can("FS::${class}", $sub)) {
+ warn "FS::XMLRPC: Can't call undefined subroutine '${fssub}'";
+ # Should we encode an error in the response,
+ # or just break silently to the remote caller and complain locally?
+ return [];
+ }
+
+ eval {
+ no strict 'refs';
+ my $fssub = "FS::${class}::${sub}";
+ @result = (&$fssub(@$params));
+ };
+
+ if ($@) {
+ warn "FS::XMLRPC: Error while calling '${fssub}': $@";
+ return [];
+ }
+
+ }
+
+ if ( scalar(@result) == 1 && ref($result[0]) eq 'HASH' ) {
+ return $result[0];
+ } elsif (grep { UNIVERSAL::can($_, 'hashref') ? 0 : 1 } @result) {
+ #warn "FS::XMLRPC: One or more objects returned from '${fssub}' doesn't " .
+ # "support the 'hashref' method.";
+
+ # If they're not FS::Record decendants, just return the results unmap'd?
+ # This is more flexible, but possibly more error-prone.
+ return [ @result ];
+ } else {
+ return [ map { $_->hashref } @result ];
+ }
+ } elsif ($method_name eq 'version') {
+ return [ $FS::VERSION ];
+ } # else...
+
+ warn "Unhandled XMLRPC request '${method_name}'";
+ return {};
}