summaryrefslogtreecommitdiff
path: root/fs_selfservice/FS-SelfService/SelfService/XMLRPC.pm
blob: 58ce6a80184b871da55b31a1eac6569e1b387583 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package FS::SelfService::XMLRPC;

=head1 NAME

FS::SelfService::XMLRPC - Freeside XMLRPC accessible self-service API

=head1 SYNOPSIS

=head1 DESCRIPTION

Use this API to implement your own client "self-service" module vi XMLRPC.

Each routine described in L<FS::SelfService> is available vi XMLRPC as the
method FS.SelfService.XMLRPC.B<method>.  All values are passed to the
selfservice-server in a struct of strings.  The return values are in a
struct as strings, arrays, or structs as appropriate for the values
described in L<FS::SelfService>.

=head1 BUGS

=head1 SEE ALSO

L<freeside-selfservice-clientd>, L<freeside-selfservice-server>,L<FS::SelfService>

=cut

use strict;
use vars qw($DEBUG $AUTOLOAD);
use XMLRPC::Lite; # for XMLRPC::Data
use FS::SelfService;

$DEBUG = 0;
$FS::SelfService::DEBUG = $DEBUG;

#false laziness w/FS::ClientAPI_XMLRPC.pm
our %typefix_skin_info = (
  'logo'              => 'base64',
  'title_left_image'  => 'base64',
  'title_right_image' => 'base64',
  'menu_top_image'    => 'base64',
  'menu_body_image'   => 'base64',
  'menu_bottom_image' => 'base64',
);
our %typefix = (
  'invoice_pdf'          => { 'invoice_pdf' => 'base64', },
  'legacy_invoice_pdf'   => { 'invoice_pdf' => 'base64', },
  'skin_info'            => \%typefix_skin_info,
  'payment_only_skin_info' => \%typefix_skin_info,
  'login_info'           => \%typefix_skin_info,
  'logout'               => \%typefix_skin_info,
  'access_info'          => \%typefix_skin_info,
  'reset_passwd'         => \%typefix_skin_info,
  'check_reset_passwd'   => \%typefix_skin_info,
  'process_reset_passwd' => \%typefix_skin_info,
  'invoice_logo'         => { 'logo'  => 'base64', },
  'login_banner_image'   => { 'image' => 'base64', },
  'quotation_print'      => { 'document' => 'base64' },
);

sub AUTOLOAD {
  my $call = $AUTOLOAD;
  $call =~ s/^FS::SelfService::XMLRPC:://;

  if (exists($FS::SelfService::autoload{$call})) {

    shift; #discard package name;

    $call = "FS::SelfService::$call";

    no strict 'refs';

    my $return = &{$call}(@_);

    if ( exists($typefix{$call}) ) {
      my $typefix = $typefix{$call};
      foreach my $field ( grep exists($return->{$_}), keys %$typefix ) {
        my $type = $typefix->{$field};
        $return->{$field} = XMLRPC::Data->value($return->{$field})
                                        ->type($type);
      }
    }

    $return;

  }else{
    die "No such procedure: $call";
  }
}

package SOAP::Transport::HTTP::Daemon;  # yuck

use POSIX qw(:sys_wait_h);

no warnings 'redefine';

sub handle {
  my $self = shift->new;

  local $SIG{CHLD} = 'IGNORE';

ACCEPT:
  while (my $c = $self->accept) {
    
    my $kid = 0;
    do {
      $kid = waitpid(-1, WNOHANG);
      warn "found kid $kid";
    } while $kid > 0;

    my $pid = fork;
    next ACCEPT if $pid;

    if ( not defined $pid ) {
      warn "fork() failed: $!";
      $c = undef;
    } else {
      while (my $r = $c->get_request) {
        $self->request($r);
        $self->SUPER::handle;
        $c->send_response($self->response);
      }
      # replaced ->close, thanks to Sean Meisner <Sean.Meisner@VerizonWireless.com>
      # shutdown() doesn't work on AIX. close() is used in this case. Thanks to Jos Clijmans <jos.clijmans@recyfin.be>
      UNIVERSAL::isa($c, 'shutdown') ? $c->shutdown(2) : $c->close(); 
      $c->close;
    }
    exit;
  }
}

1;