File Coverage

blib/lib/WWW/Namecheap/Domain.pm
Criterion Covered Total %
statement 12 123 9.7
branch 0 40 0.0
condition 0 13 0.0
subroutine 4 16 25.0
pod 11 11 100.0
total 27 203 13.3


line stmt bran cond sub pod time code
1             package WWW::Namecheap::Domain;
2              
3 1     1   1612 use 5.006;
  1         3  
  1         32  
4 1     1   4 use strict;
  1         2  
  1         26  
5 1     1   6 use warnings;
  1         2  
  1         28  
6 1     1   5 use Carp();
  1         2  
  1         1451  
7              
8             =head1 NAME
9              
10             WWW::Namecheap::Domain - Namecheap API domain methods
11              
12             =cut
13              
14             our $VERSION = '0.05';
15              
16             =head1 SYNOPSIS
17              
18             Namecheap API domain methods.
19              
20             See L for main documentation.
21              
22             use WWW::Namecheap::Domain;
23              
24             my $domain = WWW::Namecheap::Domain->new(API => $api);
25             $domain->check(...);
26             $domain->create(...);
27             ...
28              
29             =head1 SUBROUTINES/METHODS
30              
31             =head2 WWW::Namecheap::Domain->new(API => $api)
32              
33             Instantiate a new Domain object for making domain-related API calls.
34             Requires a WWW::Namecheap::API object.
35              
36             =cut
37              
38             sub new {
39 0     0 1   my $class = shift;
40            
41 0           my $params = _argparse(@_);
42            
43 0           for (qw(API)) {
44 0 0         Carp::croak("${class}->new(): Mandatory parameter $_ not provided.") unless $params->{$_};
45             }
46            
47 0           my $self = {
48             api => $params->{'API'},
49             };
50            
51 0           return bless($self, $class);
52             }
53              
54             =head2 $domain->check(Domains => ['example.com'])
55              
56             Check a list of domains. Returns a hashref of availablity status with
57             domain names as the keys and 0/1 as the values for not available/available.
58              
59             my $result = $domain->check(Domains => [qw(
60             example.com
61             example2.com
62             foobar.com
63             )]);
64            
65             Will give a $result something like:
66              
67             $result = {
68             'example.com' => 0, # example.com is taken
69             'example2.com' => 1, # example2.com is available
70             'foobar.com' => 0, # damn, foobar.com is taken
71             };
72              
73             =cut
74              
75             sub check {
76 0     0 1   my $self = shift;
77            
78 0           my $params = _argparse(@_);
79            
80 0           my %domains = map { $_ => -1 } @{$params->{'Domains'}};
  0            
  0            
81 0           my $DomainList = join(',', keys %domains);
82 0           my $xml = $self->api->request(
83             Command => 'namecheap.domains.check',
84             ClientIp => $params->{'ClientIp'},
85             UserName => $params->{'UserName'},
86             DomainList => $DomainList,
87             );
88            
89 0 0         return unless $xml;
90            
91 0           foreach my $entry (@{$xml->{CommandResponse}->{DomainCheckResult}}) {
  0            
92 0 0         unless ($domains{$entry->{Domain}}) {
93 0           Carp::carp("Unexpected domain found: $entry->{Domain}");
94 0           next;
95             }
96 0 0         if ($entry->{Available} eq 'true') {
97 0           $domains{$entry->{Domain}} = 1;
98             } else {
99 0           $domains{$entry->{Domain}} = 0;
100             }
101             }
102            
103 0           return \%domains;
104             }
105              
106             =head2 $domain->create(%hash)
107              
108             Register a new domain name.
109              
110             Example:
111              
112             my $result = $domain->create(
113             UserName => 'username', # optional if DefaultUser specified in $api
114             ClientIp => '1.2.3.4', # optional if DefaultIp specified in $api
115             DomainName => 'example.com',
116             Years => 1,
117             Registrant => {
118             OrganizationName => 'Example Dot Com', # optional
119             FirstName => 'Domain',
120             LastName => 'Manager',
121             Address1 => '123 Fake Street',
122             Address2 => 'Suite 555', # optional
123             City => 'Univille',
124             StateProvince => 'SD',
125             StateProvinceChoice => 'S', # for 'State' or 'P' for 'Province'
126             PostalCode => '12345',
127             Country => 'US',
128             Phone => '+1.2025551212',
129             Fax => '+1.2025551212', # optional
130             EmailAddress => 'foo@example.com',
131             },
132             Tech => {
133             # same fields as Registrant
134             },
135             Admin => {
136             # same fields as Registrant
137             },
138             AuxBilling => {
139             # same fields as Registrant
140             },
141             Nameservers => 'ns1.foo.com,ns2.bar.com', # optional
142             AddFreeWhoisguard => 'yes', # or 'no', default 'yes'
143             WGEnabled => 'yes', # or 'no', default 'yes'
144             );
145              
146             Unspecified contacts will be automatically copied from the registrant, which
147             must be provided.
148              
149             Returns:
150              
151             $result = {
152             Domain => 'example.com',
153             DomainID => '12345',
154             Registered => 'true',
155             OrderID => '12345',
156             TransactionID => '12345',
157             ChargedAmount => '10.45', # dollars and cents
158             };
159              
160             =cut
161              
162             sub create {
163 0     0 1   my $self = shift;
164            
165 0           my $params = _argparse(@_);
166            
167 0   0       my %request = (
      0        
168             Command => 'namecheap.domains.create',
169             ClientIp => $params->{'ClientIp'},
170             UserName => $params->{'UserName'},
171             DomainName => $params->{'DomainName'},
172             Years => $params->{Years},
173             Nameservers => $params->{'Nameservers'},
174             AddFreeWhoisguard => $params->{'AddFreeWhoisguard'} || 'yes',
175             WGEnabled => $params->{'WGEnabled'} || 'yes',
176             );
177            
178 0           foreach my $contact (qw(Registrant Tech Admin AuxBilling)) {
179 0   0       $params->{$contact} ||= $params->{Registrant};
180 0           map { $request{"$contact$_"} = $params->{$contact}{$_} } keys %{$params->{$contact}};
  0            
  0            
181             }
182            
183 0           my $xml = $self->api->request(%request);
184            
185 0 0         return unless $xml;
186            
187 0           return $xml->{CommandResponse}->{DomainCreateResult};
188             }
189              
190             =head2 $domain->list(%hash)
191              
192             Get a list of domains in your account. Automatically handles the Namecheap
193             "paging" to get a full list. May be optionally restricted:
194              
195             my $domains = $domain->list(
196             ListType => 'ALL', # or EXPIRING or EXPIRED
197             SearchTerm => 'foo', # keyword search
198             SortBy => 'NAME', # or EXPIREDATE, CREATEDATE, or *_DESC
199             );
200              
201             Returns an arrayref of hashrefs:
202              
203             $domains = [
204             {
205             ID => '123',
206             Name => 'example.com',
207             User => 'owner',
208             Created => 'MM/DD/YYYY',
209             Expires => 'MM/DD/YYYY',
210             IsExpired => 'false',
211             IsLocked => 'true',
212             AutoRenew => 'false',
213             WhoisGuard => 'ENABLED',
214             },
215             ...
216             ];
217              
218             =cut
219              
220             sub list {
221 0     0 1   my $self = shift;
222            
223 0           my $params = _argparse(@_);
224            
225 0           my %request = (
226             Command => 'namecheap.domains.getList',
227             ClientIp => $params->{'ClientIp'},
228             UserName => $params->{'UserName'},
229             PageSize => 100,
230             Page => 1,
231             ListType => $params->{'ListType'},
232             SearchTerm => $params->{'SearchTerm'},
233             );
234            
235 0           my @domains;
236            
237 0           my $break = 0;
238 0           while (1) {
239 0           my $xml = $self->api->request(%request);
240            
241 0 0         last unless $xml;
242            
243 0 0         if (ref($xml->{CommandResponse}->{DomainGetListResult}->{Domain}) eq 'ARRAY') {
    0          
244 0           push(@domains, @{$xml->{CommandResponse}->{DomainGetListResult}->{Domain}});
  0            
245             } elsif (ref($xml->{CommandResponse}->{DomainGetListResult}->{Domain}) eq 'HASH') {
246 0           push(@domains, $xml->{CommandResponse}->{DomainGetListResult}->{Domain});
247             } else {
248 0           Carp::carp('Unexpected XML in CommandResponse->DomainGetListResult->Domain!');
249             }
250 0 0         if ($xml->{CommandResponse}->{Paging}->{TotalItems} <= ($request{Page} * $request{PageSize})) {
251 0           last;
252             } else {
253 0           $request{Page}++;
254             }
255             }
256            
257 0           return \@domains;
258             }
259              
260             =head2 $domain->getcontacts(DomainName => 'example.com')
261              
262             Get the contacts on file for the provided DomainName. Returns a big
263             ol' data structure:
264              
265             $contacts = {
266             Domain => 'example.com',
267             domainnameid => '12345',
268             Registrant => {
269             ReadOnly => 'false',
270             ... all contact fields from create ...
271             },
272             Tech => {
273             ... ditto ...
274             },
275             Admin => {
276             ... ditto ...
277             },
278             AuxBilling => {
279             ... ditto ...
280             },
281             WhoisGuardContact => {
282             ... same contacts as outside, except the actual published
283             WhoisGuard info, ReadOnly => 'true' ...
284             },
285             };
286              
287             =cut
288              
289             sub getcontacts {
290 0     0 1   my $self = shift;
291            
292 0           my $params = _argparse(@_);
293            
294 0 0         return unless $params->{'DomainName'};
295            
296 0           my %request = (
297             Command => 'namecheap.domains.getContacts',
298             %$params,
299             );
300            
301 0           my $xml = $self->api->request(%request);
302            
303 0 0         return unless $xml;
304            
305 0           return $xml->{CommandResponse}->{DomainContactsResult};
306             }
307              
308             =head2 $domain->setcontacts(%hash)
309              
310             Set contacts for a domain name.
311              
312             Example:
313              
314             my $result = $domain->create(
315             UserName => 'username', # optional if DefaultUser specified in $api
316             ClientIp => '1.2.3.4', # optional if DefaultIp specified in $api
317             DomainName => 'example.com',
318             Registrant => {
319             OrganizationName => 'Example Dot Com', # optional
320             FirstName => 'Domain',
321             LastName => 'Manager',
322             Address1 => '123 Fake Street',
323             Address2 => 'Suite 555', # optional
324             City => 'Univille',
325             StateProvince => 'SD',
326             StateProvinceChoice => 'S', # for 'State' or 'P' for 'Province'
327             PostalCode => '12345',
328             Country => 'USA',
329             Phone => '+1.2025551212',
330             Fax => '+1.2025551212', # optional
331             EmailAddress => 'foo@example.com',
332             },
333             Tech => {
334             # same fields as Registrant
335             },
336             Admin => {
337             # same fields as Registrant
338             },
339             AuxBilling => {
340             # same fields as Registrant
341             },
342             );
343              
344             Unspecified contacts will be automatically copied from the registrant, which
345             must be provided.
346              
347             $result is a small hashref confirming back the domain that was modified
348             and whether the operation was successful or not:
349              
350             $result = {
351             Domain => 'example.com',
352             IsSuccess => 'true',
353             };
354              
355             =cut
356              
357             sub setcontacts {
358 0     0 1   my $self = shift;
359            
360 0           my $params = _argparse(@_);
361            
362 0 0         return unless $params->{'DomainName'};
363            
364 0           my %request = (
365             Command => 'namecheap.domains.setContacts',
366             ClientIp => $params->{'ClientIp'},
367             UserName => $params->{'UserName'},
368             DomainName => $params->{'DomainName'},
369             );
370            
371 0           foreach my $contact (qw(Registrant Tech Admin AuxBilling)) {
372 0   0       $params->{$contact} ||= $params->{Registrant};
373 0           map { $request{"$contact$_"} = $params->{$contact}{$_} } keys %{$params->{$contact}};
  0            
  0            
374             }
375            
376 0           my $xml = $self->api->request(%request);
377            
378 0 0         return unless $xml;
379            
380 0           return $xml->{CommandResponse}->{DomainSetContactResult};
381             }
382              
383             =head2 $domain->gettldlist()
384              
385             Get a list of all TLDs available for registration, along with various
386             attributes for each TLD. Results are automatically cached for one
387             hour to avoid excessive API load.
388              
389             =cut
390              
391             sub gettldlist {
392 0     0 1   my $self = shift;
393            
394 0           my $params = _argparse(@_);
395            
396 0           my %request = (
397             Command => 'namecheap.domains.getTldList',
398             %$params,
399             );
400            
401 0 0 0       if (!$self->{_tldlist_cachetime} || time() - $self->{_tldlist_cachetime} > 3600) {
402 0           my $xml = $self->api->request(%request);
403 0           $self->{_tldlist_cache} = $xml->{CommandResponse}->{Tlds}->{Tld};
404 0           $self->{_tldlist_cachetime} = time();
405             }
406            
407 0           return $self->{_tldlist_cache};
408             }
409              
410             =head2 $domain->transfer(%hash)
411              
412             Initiate a transfer in request to Namecheap from another registrar.
413             Request should look something like:
414              
415             my $transfer = $domain->transfer(
416             DomainName => 'example.com',
417             Years => 1,
418             EPPCode => 'foobarbaz',
419             );
420              
421             The response will be a hashref:
422              
423             $transfer = {
424             Transfer => 'true',
425             TransferID => '15',
426             StatusID => '-1',
427             OrderID => '1234',
428             TransactionID => '1234',
429             ChargedAmount => '10.10',
430             };
431              
432             For transfer status code details, see the Namecheap API documentation:
433              
434             L
435              
436             =cut
437              
438             sub transfer {
439 0     0 1   my $self = shift;
440            
441 0           my $params = _argparse(@_);
442            
443 0           my %request = (
444             Command => 'namecheap.domains.transfer.create',
445             %$params,
446             );
447            
448 0           my $xml = $self->api->request(%request);
449            
450 0 0         return unless $xml;
451            
452 0           return $xml->{CommandResponse}->{DomainTransferCreateResult};
453             }
454              
455             =head2 $domain->transferstatus(TransferID => '1234')
456              
457             Check the current status of a particular transfer. The TransferID
458             is the TransferID returned by the transfer() call, or included in
459             the transferlist(). Returns a hashref:
460              
461             $result = {
462             TransferID => '1234',
463             Status => 'String',
464             StatusID => '-1',
465             };
466              
467             =cut
468              
469             sub transferstatus {
470 0     0 1   my $self = shift;
471            
472 0           my $params = _argparse(@_);
473            
474 0           my %request = (
475             Command => 'namecheap.domains.transfer.getStatus',
476             %$params,
477             );
478            
479 0           my $xml = $self->api->request(%request);
480            
481 0 0         return unless $xml;
482            
483 0           return $xml->{CommandResponse}->{DomainTransferGetStatusResult};
484             }
485              
486             =head2 $domain->transferlist()
487              
488             Retrieve a list of transfers associated with the connected API account.
489             Automatically handles the Namecheap "paging" to get a full list. May
490             be optionally restricted:
491              
492             my $transfers = $domain->transferlist(
493             ListType => 'ALL', # or INPROGRESS, CANCELLED, COMPLETED
494             SearchTerm => 'foo', # keyword search
495             SortBy => 'DOMAINNAME', # or TRANSFERDATE, STATUSDATE, *_DESC
496             );
497              
498             Returns an arrayref of hashrefs:
499              
500             $domains = [
501             {
502             ID => '123',
503             DomainName => 'example.com',
504             User => 'apiuser',
505             TransferDate => 'MM/DD/YYYY',
506             OrderID => 12345,
507             StatusID => 20
508             Status => 'Cancelled',
509             StatusDate => 'MM/DD/YYYY',
510             StatusDescription => 'String',
511             }
512             ...
513             ];
514              
515             =cut
516              
517             sub transferlist {
518 0     0 1   my $self = shift;
519            
520 0           my $params = _argparse(@_);
521            
522 0           my %request = (
523             Command => 'namecheap.domains.transfer.getList',
524             ClientIp => $params->{'ClientIp'},
525             UserName => $params->{'UserName'},
526             PageSize => 100,
527             Page => 1,
528             ListType => $params->{'ListType'},
529             SearchTerm => $params->{'SearchTerm'},
530             );
531            
532 0           my @transfers;
533            
534 0           my $break = 0;
535 0           while (1) {
536 0           my $xml = $self->api->request(%request);
537            
538 0 0         last unless $xml;
539            
540 0           push(@transfers, @{$xml->{CommandResponse}->{TransferGetListResult}->{Transfer}});
  0            
541 0 0         if ($xml->{CommandResponse}->{Paging}->{TotalItems} <= ($request{Page} * $request{PageSize})) {
542 0           last;
543             } else {
544 0           $request{Page}++;
545             }
546             }
547            
548 0           return \@transfers;
549             }
550              
551             =head2 $domain->api()
552              
553             Accessor for internal API object.
554              
555             =cut
556              
557             sub api {
558 0     0 1   return $_[0]->{api};
559             }
560              
561             sub _argparse {
562 0     0     my $hashref;
563 0 0         if (@_ % 2 == 0) {
    0          
564 0           $hashref = { @_ }
565             } elsif (ref($_[0]) eq 'HASH') {
566 0           $hashref = \%{$_[0]};
  0            
567             }
568 0           return $hashref;
569             }
570              
571             =head1 AUTHOR
572              
573             Tim Wilde, C<< >>
574              
575             =head1 BUGS
576              
577             Please report any bugs or feature requests to C, or through
578             the web interface at L. I will be notified, and then you'll
579             automatically be notified of progress on your bug as I make changes.
580              
581              
582              
583             =head1 SUPPORT
584              
585             You can find documentation for this module with the perldoc command.
586              
587             perldoc WWW::Namecheap::Domain
588              
589              
590             You can also look for information at:
591              
592             =over 4
593              
594             =item * RT: CPAN's request tracker (report bugs here)
595              
596             L
597              
598             =item * AnnoCPAN: Annotated CPAN documentation
599              
600             L
601              
602             =item * CPAN Ratings
603              
604             L
605              
606             =item * Search CPAN
607              
608             L
609              
610             =back
611              
612              
613             =head1 ACKNOWLEDGEMENTS
614              
615              
616             =head1 LICENSE AND COPYRIGHT
617              
618             Copyright 2011 Tim Wilde.
619              
620             This program is free software; you can redistribute it and/or modify it
621             under the terms of either: the GNU General Public License as published
622             by the Free Software Foundation; or the Artistic License.
623              
624             See http://dev.perl.org/licenses/ for more information.
625              
626              
627             =cut
628              
629             1; # End of WWW::Namecheap::Domain