1# Copyright (c) 2003-2004 Timothy Appnel (cpan@timaoutloud.org)
2# http://www.timaoutloud.org/
3# This code is released under the Artistic License.
4package Net::Trackback::Ping;
5use strict;
6use base qw( Class::ErrorHandler );
7
8my %fields;
9map { $fields{$_}=1 }
10    qw( title excerpt url blog_name timestamp ping_url id);
11
12sub new {
13    my $self = bless {}, $_[0];
14    # Should we filter out unknown fields?
15    $self->{__stash} = $_[1] if $_[1];
16    $self;
17}
18
19sub parse {
20    my $class = shift;
21    my $q = shift;
22    my $tb_id = $q->param('tb_id');
23    unless ($tb_id) {
24        if ( my $pi = $q->path_info() ) {
25            ( $tb_id = $pi ) =~ s!^/!!;
26        }
27    }
28    return $class->error('No Trackback ID (tb_id)') unless $tb_id;
29    $tb_id =~ tr/a-zA-Z0-9/_/cs;
30    return $class->error('No URL (url)') unless $q->param('url');
31    my $self = $class->new();
32    $self->{__stash} =
33        { map { $_ => scalar $q->param($_) }
34            keys %fields };
35    $self->{__stash}->{id} = $tb_id;
36    $self->{__stash}->{title} ||= $self->{__stash}->{url};
37    $self->{__stash}->{timestamp} = time;
38    $self;
39}
40
41sub to_hash { %{ $_[0]->{__stash} } }
42
43sub to_urlencoded {
44    my $self = shift;
45    my $stash = $self->{__stash};
46    my $str;
47    foreach (grep { $stash->{$_} } keys %fields) {
48        next if ($_ eq 'ping_url' || $_ eq 'timestamp');
49        $str .= '&' if $str;
50        (my $val = $stash->{$_})
51            =~s!([^a-zA-Z0-9_.-])!uc sprintf "%%%02x",ord($1)!eg;
52        $str .= "$_=$val";
53    }
54    $str;
55}
56
57DESTROY { }
58
59use vars qw( $AUTOLOAD );
60sub AUTOLOAD {
61    (my $var = $AUTOLOAD) =~ s!.+::!!;
62    no strict 'refs';
63    die "$var is not a recognized method."
64        unless ( $fields{$var} );
65    *$AUTOLOAD = sub {
66        $_[0]->{__stash}->{$var} = $_[1] if $_[1];
67        $_[0]->{__stash}->{$var};
68    };
69    goto &$AUTOLOAD;
70}
71
721;
73
74__END__
75
76=begin
77
78=head1 NAME
79
80Net::Trackback::Ping - an object representing a Trackback ping.
81
82=head1 SYNOPSIS
83
84 use Net::Trackback::Client;
85 use Net::Trackback::Ping;
86 my $ping = Net::Trackback::Ping->new();
87 $ping->title('Net::Trackback Test');
88 $ping->url('http://search.cpan.org/search?query=Trackback');
89 $ping->ping_url('http://www.movabletype.org/mt/trackback/62');
90 my $client = Net::Trackback::Client->new();
91 my $msg = $client->send_ping($ping);
92 print $msg->to_xml;
93
94=head1 METHODS
95
96=item Net::Trackback::Ping->new([$hashref])
97
98Constuctor method. It will initialize the object if passed a
99hash reference. Recognized keys are url, ping_url, id, title,
100excerpt, and blogname. These keys correspond to the methods
101like named methods.
102
103=item Net::Trackback::Ping->parse($CGI)
104
105A method that extracts ping data from an HTTP request and returns a
106ping object. In the event a bad ping has been passed in the method
107will return C<undef>. USe the C<errstr> method to retrieve the
108error message. One required parameter, a reference to a L<CGI>
109object or some other that has a C<param> method that works just
110like it. See the list of recognized keys in the L<new> method.
111
112=item $ping->url([$url])
113
114Accessor to a resource URL. Passing in an optional string parameter
115sets the value. This value is required to make a ping.
116
117=item $ping->ping_url([$url])
118
119Accessor to the URL to ping with the resource's Trackback
120information. Passing in an optional string parameter sets the
121value. This value is required to make a ping.
122
123=item $ping->id([$id])
124
125Accessor to the remote resource ID that is to be pinged. Passing in
126an optional string parameter sets the value.
127
128=item $ping->title([$title])
129
130Accessor to the title of resource that is to be pinged. Passing in an
131optional string parameter sets the value.
132
133=item $ping->excerpt([$excerpt]);
134
135A brief plain text description of the resource at the other end of
136the L<url>. Passing in an optional string parameter sets the value.
137
138B<NOTE:> While the Trackback specification doesn't specify a limit
139to the size of an excerpt, some implementations do. For instance as
140of Movable Type 3.14, Trackback excerpts cannot exceed 255
141characters.
142
143=item $ping->blog_name([$source]);
144
145Accessor to the source of the ping. Passing in an optional string
146parameter sets the value.
147
148=item $ping->to_hash
149
150Returns a hash of the object's current state.
151
152=item $ping->to_urlencoded
153
154Returns a URL encoded string of the object's current state.
155
156=head2 Errors
157
158This module is a subclass of L<Class::ErrorHandler> and inherits
159two methods for passing error message back to a caller.
160
161=item Class->error($message)
162
163=item $object->error($message)
164
165Sets the error message for either the class Class or the object
166$object to the message $message. Returns undef.
167
168=item Class->errstr
169
170=item $object->errstr
171
172Accesses the last error message set in the class Class or the
173object $object, respectively, and returns that error message.
174
175=head1 AUTHOR & COPYRIGHT
176
177Please see the Net::Trackback manpage for author, copyright, and
178license information.
179
180=cut
181
182=end