File Coverage

blib/lib/WWW/Challonge/Tournament.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package WWW::Challonge::Tournament;
2              
3 1     1   14 use 5.006;
  1         2  
  1         33  
4 1     1   4 use strict;
  1         1  
  1         25  
5 1     1   10 use warnings;
  1         1  
  1         22  
6 1     1   283 use WWW::Challonge::Participant;
  0            
  0            
7             use WWW::Challonge::Match;
8             use JSON qw/to_json from_json/;
9              
10             sub __is_kill;
11             sub __args_are_valid;
12              
13             =head1 NAME
14              
15             WWW::Challonge::Tournament - A class representing a single Challonge tournament.
16              
17             =head1 VERSION
18              
19             Version 0.10
20              
21             =cut
22              
23             our $VERSION = '0.10';
24              
25             =head1 SUBROUTINES/METHODS
26              
27             =head2 new
28              
29             Takes a hashref representing the tournament, the API key and the REST client
30             and turns it into an object. This is mostly used by the module itself, to
31             create a new tournament see L.
32              
33             my $t = WWW::Challonge::Tournament->new($tournament, $key, $client);
34              
35             =cut
36              
37             sub new
38             {
39             my $class = shift;
40             my $tournament = shift;
41             my $key = shift;
42             my $client = shift;
43              
44             my $t =
45             {
46             alive => 1,
47             client => $client,
48             tournament => $tournament->{tournament},
49             key => $key,
50             };
51             bless $t, $class;
52             }
53              
54             =head2 update
55              
56             Updates specific attributes of a tournament. For a full list, see
57             L. Unlike that method, however, all of the arguments
58             are optional.
59              
60             $t->update({
61             name => "sample_tournament_2",
62             type => "swiss",
63             });
64              
65             =cut
66              
67             sub update
68             {
69             my $self = shift;
70             my $args = shift;
71              
72             # Do not operate on a dead tournament:
73             return __is_kill unless($self->{alive});
74              
75             # Get the key, REST client and tournament url:
76             my $key = $self->{key};
77             my $client = $self->{client};
78             my $url = $self->{tournament}->{url};
79              
80             # Check the arguments and values are valid:
81             return undef unless(WWW::Challonge::Tournament::__args_are_valid($args));
82              
83             # Add the API key and put everything else in a 'tournament' hash:
84             my $params = { api_key => $key, tournament => $args };
85              
86             # Make the PUT request:
87             $client->PUT("/tournaments/$url.json", to_json($params),
88             { "Content-Type" => 'application/json' });
89              
90             # Check if it was successful:
91             if($client->responseCode > 300)
92             {
93             my $errors = from_json($client->responseContent)->{errors};
94             for my $error(@{$errors})
95             {
96             print STDERR "Error: $error\n";
97             }
98             return undef;
99             }
100              
101             # If so, update the object's store of the tournament:
102             $self->{tournament} = from_json($client->responseContent)->{tournament};
103             }
104              
105             =head2 destroy
106              
107             Deletes the tournament from the user's account. There is no undo, so use with
108             care!
109              
110             $t->destroy;
111              
112             # $t still contains the tournament, but any future operations will fail:
113             $t->update({ name => "sample_tournament_2" }); # ERROR!
114              
115             =cut
116              
117             sub destroy
118             {
119             my $self = shift;
120              
121             # Do not operate on a dead tournament:
122             return __is_kill unless($self->{alive});
123              
124             # Get the key, REST client and tournament URL:
125             my $key = $self->{key};
126             my $client = $self->{client};
127             my $url = $self->{tournament}->{url};
128              
129             # Make the DELETE call:
130             $client->DELETE("/tournaments/$url.json?api_key=$key");
131              
132             # Check if it was successful:
133             if($client->responseCode > 300)
134             {
135             my $errors = from_json($client->responseContent)->{errors};
136             for my $error(@{$errors})
137             {
138             print STDERR "Error: $error\n";
139             }
140             return undef;
141             }
142              
143             # Set the tournament to dead to prevent further operations:
144             $self->{alive} = 0;
145             }
146              
147             =head2 process_check_ins
148              
149             This should be invoked after a tournament's check-in window closes, but before
150             the tournament is started. It then does the following:
151              
152             =over 4
153              
154             =item 1
155              
156             Marks participants who have not checked in as inactive.
157              
158             =item 2
159              
160             Moves inactive participants to the bottom seeds.
161              
162             =item 3
163              
164             Transitions the tournament state from "checking_in" to "checked_in".
165              
166             =back
167              
168             $t->process_check_ins;
169              
170             =cut
171              
172             sub process_check_ins
173             {
174             my $self = shift;
175              
176             # Do not operate on a dead tournament:
177             return __is_kill unless($self->{alive});
178              
179             # Get the key, REST client and tournament URL:
180             my $key = $self->{key};
181             my $client = $self->{client};
182             my $url = $self->{tournament}->{url};
183              
184             # Send the API key:
185             my $params = { api_key => $key };
186              
187             # Make the POST call:
188             $client->POST("/tournaments/$url/process_check_ins.json", to_json($params),
189             { "Content-Type" => 'application/json' });
190              
191             # Check if it was successful:
192             if($client->responseCode > 300)
193             {
194             my $errors = from_json($client->responseContent)->{errors};
195             for my $error(@{$errors})
196             {
197             print STDERR "Error: $error\n";
198             }
199             return undef;
200             }
201              
202             # If so, update the object's store of the tournament:
203             $self->{tournament}->{state} = "checked_in";
204             }
205              
206             =head2 abort_check_in
207              
208             Aborts the check-in process if the tournament's status is currently
209             "checking_in" or "checked_in". This is useful as you cannot edit the
210             tournament's start time during this state. It does the following:
211              
212             =over 4
213              
214             =item 1
215              
216             Makes all participants active and clears their "checked_in_at" times.
217              
218             =item 2
219              
220             Sets the tournament state from "checking_in" or "checked_in" to "pending".
221              
222             =back
223              
224             $t->abort_check_in;
225              
226             =cut
227              
228             sub abort_check_in
229             {
230             my $self = shift;
231              
232             # Do not operate on a dead tournament:
233             return __is_kill unless($self->{alive});
234              
235             # Get the key, REST client and tournament URL:
236             my $key = $self->{key};
237             my $client = $self->{client};
238             my $url = $self->{tournament}->{url};
239              
240             # Send the API key:
241             my $params = { api_key => $key };
242              
243             # Make the POST call:
244             $client->POST("/tournaments/$url/abort_check_in.json", to_json($params),
245             { "Content-Type" => 'application/json' });
246              
247             # Check if it was successful:
248             if($client->responseCode > 300)
249             {
250             my $errors = from_json($client->responseContent)->{errors};
251             for my $error(@{$errors})
252             {
253             print STDERR "Error: $error\n";
254             }
255             return undef;
256             }
257              
258             # If so, update the object's store of the tournament:
259             $self->{tournament}->{state} = "pending";
260             }
261              
262             =head2 start
263              
264             Starts a tournament, opening up matches for score reporting. The tournament
265             must have at least 2 participants. If successful, sets the status of the
266             tournament to "in_progress".
267              
268             $t->start;
269              
270             =cut
271              
272             sub start
273             {
274             my $self = shift;
275              
276             # Do not operate on a dead tournament:
277             return __is_kill unless($self->{alive});
278              
279             # Get the key, REST client and tournament URL:
280             my $key = $self->{key};
281             my $client = $self->{client};
282             my $url = $self->{tournament}->{url};
283              
284             # Send the API key:
285             my $params = { api_key => $key };
286              
287             # Make the POST call:
288             $client->POST("/tournaments/$url/start.json", to_json($params),
289             { "Content-Type" => 'application/json' });
290              
291             # Check if it was successful:
292             if($client->responseCode > 300)
293             {
294             my $errors = from_json($client->responseContent)->{errors};
295             for my $error(@{$errors})
296             {
297             print STDERR "Error: $error\n";
298             }
299             return undef;
300             }
301              
302             # If so, update the object's store of the tournament:
303             $self->{tournament}->{state} = "in_progress";
304             }
305              
306             =head2 finalize
307              
308             Finalises a tournament that has had all match scores submitted, rendering the
309             results permenant. If successful, it sets the status to "ended".
310              
311             $t->finalize;
312              
313             =cut
314              
315             sub finalize
316             {
317             my $self = shift;
318              
319             # Do not operate on a dead tournament:
320             return __is_kill unless($self->{alive});
321              
322             # Get the key, REST client and tournament URL:
323             my $key = $self->{key};
324             my $client = $self->{client};
325             my $url = $self->{tournament}->{url};
326              
327             # Send the API key:
328             my $params = { api_key => $key };
329              
330             # Make the POST call:
331             $client->POST("/tournaments/$url/finalize.json", to_json($params),
332             { "Content-Type" => 'application/json' });
333              
334             # Check if it was successful:
335             if($client->responseCode > 300)
336             {
337             my $errors = from_json($client->responseContent)->{errors};
338             for my $error(@{$errors})
339             {
340             print STDERR "Error: $error\n";
341             }
342             return undef;
343             }
344              
345             # If so, update the object's store of the tournament:
346             $self->{tournament}->{state} = "ended";
347             }
348              
349             =head2 reset
350              
351             Resets an "in_progress" tournament, deleting all match records. You can add,
352             remove or edit users before starting again.
353              
354             $t->reset;
355              
356             =cut
357              
358             sub reset
359             {
360             my $self = shift;
361              
362             # Do not operate on a dead tournament:
363             return __is_kill unless($self->{alive});
364              
365             # Get the key, REST client and tournament URL:
366             my $key = $self->{key};
367             my $client = $self->{client};
368             my $url = $self->{tournament}->{url};
369              
370             # Send the API key:
371             my $params = { api_key => $key };
372              
373             # Make the POST call:
374             $client->POST("/tournaments/$url/reset.json", to_json($params),
375             { "Content-Type" => 'application/json' });
376              
377             # Check if it was successful:
378             if($client->responseCode > 300)
379             {
380             my $errors = from_json($client->responseContent)->{errors};
381             for my $error(@{$errors})
382             {
383             print STDERR "Error: $error\n";
384             }
385             return undef;
386             }
387              
388             # If so, update the object's store of the tournament:
389             $self->{tournament}->{state} = "ended";
390             }
391              
392             =head2 attributes
393              
394             Gets all the attributes of the tournament in a hashref. Contains the following
395             fields.
396              
397             =over 4
398              
399             =item accepting_predictions
400              
401             =item accept_attachments
402              
403             =item allow_participant_match_reporting
404              
405             =item anonymous_voting
406              
407             =item category
408              
409             =item check_in_duration
410              
411             =item completed_at
412              
413             =item created_at
414              
415             =item created_by_api
416              
417             =item credit_capped
418              
419             =item description
420              
421             =item description_source
422              
423             =item full_challonge_url
424              
425             =item game_id
426              
427             =item game_name
428              
429             =item group_stages_enabled
430              
431             =item group_stages_were_started
432              
433             =item hide_forum
434              
435             =item hide_seeds
436              
437             =item hold_third_place_match
438              
439             =item id
440              
441             =item live_image_url
442              
443             =item max_predictions_per_user
444              
445             =item name
446              
447             =item notify_users_when_match_opens
448              
449             =item notify_users_when_the_tournament_ends
450              
451             =item open_signup
452              
453             =item participants_count
454              
455             =item participants_locked
456              
457             =item participants_swappable
458              
459             =item prediction_method
460              
461             =item predictions_opened_at
462              
463             =item private
464              
465             =item progress_meter
466              
467             =item pts_for_bye
468              
469             =item pts_for_game_tie
470              
471             =item pts_for_game_win
472              
473             =item pts_for_match_tie
474              
475             =item pts_for_match_win
476              
477             =item quick_advance
478              
479             =item ranked_by
480              
481             =item review_before_finalizing
482              
483             =item require_score_agreement
484              
485             =item rr_pts_for_game_tie
486              
487             =item rr_pts_for_game_win
488              
489             =item rr_pts_for_match_tie
490              
491             =item rr_pts_for_match_win
492              
493             =item sequential pairings
494              
495             =item show_rounds
496              
497             =item signup_cap
498              
499             =item sign_up_url
500              
501             =item start_at
502              
503             =item started_at
504              
505             =item started_checking_in_at
506              
507             =item state
508              
509             =item swiss_rounds
510              
511             =item subdomain
512              
513             =item teams
514              
515             =item team_convertable
516              
517             =item tie_breaks
518              
519             =item tournament_type
520              
521             =item updated_at
522              
523             =item url
524              
525             =back
526              
527             my $attr = $t->attributes;
528             print $attr->{name}, "\n";
529              
530             =cut
531              
532             sub attributes
533             {
534             my $self = shift;
535              
536             # Do not operate on a dead tournament:
537             return __is_kill unless($self->{alive});
538              
539             # Get the key, REST client and url:
540             my $key = $self->{key};
541             my $client = $self->{client};
542             my $url = $self->{tournament}->{url};
543              
544             # Get the most recent version:
545             $client->GET("/tournaments/$url.json?api_key=$key");
546              
547             # Check if it was successful:
548             if($client->responseCode > 300)
549             {
550             my $errors = from_json($client->responseContent)->{errors};
551             for my $error(@{$errors})
552             {
553             print STDERR "Error: $error\n";
554             }
555             return undef;
556             }
557              
558             # Save the most recent version and return it:
559             $self->{tournament} = from_json($client->responseContent)->{tournament};
560             return $self->{tournament};
561             }
562              
563             =head2 participant_index
564              
565             Returns an arrayref of C objects for every
566             participant in the tourney.
567              
568             my $p = $t->participant_index;
569             for my $participant(@{$p})
570             {
571             ...
572              
573             =cut
574              
575             sub participant_index
576             {
577             my $self = shift;
578              
579             # Do not operate on a dead tournament:
580             return __is_kill unless($self->{alive});
581              
582             # Get the key, REST client and url:
583             my $key = $self->{key};
584             my $client = $self->{client};
585             my $url = $self->{tournament}->{url};
586              
587             # Make the GET request:
588             $client->GET("/tournaments/$url/participants.json?api_key=$key");
589              
590             # Check if it was successful:
591             if($client->responseCode > 300)
592             {
593             my $errors = from_json($client->responseContent)->{errors};
594             for my $error(@{$errors})
595             {
596             print STDERR "Error: $error\n";
597             }
598             return undef;
599             }
600              
601             # If so, make an object for every participant:
602             my $participants = [];
603             for my $participant(@{from_json($client->responseContent)})
604             {
605             push @{$participants}, WWW::Challonge::Participant->new($participant,
606             $key, $client);
607             }
608             return $participants;
609             }
610              
611             =head2 participant_show
612              
613             Returns a single C object representing the
614             participant with the given unique ID.
615              
616             my $p = $t->participant_show(24279875);
617              
618             =cut
619              
620             sub participant_show
621             {
622             my $self = shift;
623             my $participant = shift;
624              
625             # Do not operate on a dead tournament:
626             return __is_kill unless($self->{alive});
627              
628             # Get the key, REST client and url:
629             my $key = $self->{key};
630             my $client = $self->{client};
631             my $url = $self->{tournament}->{url};
632              
633             # Make the GET request:
634             $client->GET("/tournaments/$url/participants/$participant.json?api_key=$key");
635              
636             # Check if it was successful:
637             if($client->responseCode > 300)
638             {
639             my $errors = from_json($client->responseContent)->{errors};
640             for my $error(@{$errors})
641             {
642             print STDERR "Error: $error\n";
643             }
644             return undef;
645             }
646              
647             # If so, create an object and return it:
648             my $p = WWW::Challonge::Participant->new(from_json($client->responseContent),
649             $key, $client);
650             return $p;
651             }
652              
653             =head2 participant_create
654              
655             Adds a new participant to the tournament, and if successful returns the newly
656             created C object. The possible arguments are as
657             follows.
658              
659             =over 4
660              
661             =item name
662              
663             The name of the participant. Required unless I or I
664             are provided. Must be unique within the tournament.
665              
666             =item challonge_username
667              
668             If the participant has a valid Challonge account, providing a name will send
669             them an invite to join the tournament.
670              
671             =item email
672              
673             If the email is attached to a valid Challonge account, it will invite them to
674             join the tournament. If not, the 'new-user-email' attribute will be set, and
675             an email will be sent to invite the person to join Challonge.
676              
677             =item seed
678              
679             Integer. The participant's new seed. Must be between 1 and the new number of
680             participants. Overwriting an existing seed will bump up the other participants.
681             If none is given, the participant will be given the lowest possible seed (the
682             bottom).
683              
684             =item misc
685              
686             Miscellaneous notes on a player only accessible via the API. Maximum 255
687             characters.
688              
689             =back
690              
691             my $p = $t->participant_create({
692             name => "test",
693             seed => 4
694             });
695              
696             =cut
697              
698             sub participant_create
699             {
700             my $self = shift;
701             my $args = shift;
702              
703             # Do not operate on a dead tournament:
704             return __is_kill unless($self->{alive});
705              
706             # Get the key, REST client and url:
707             my $key = $self->{key};
708             my $client = $self->{client};
709             my $url = $self->{tournament}->{url};
710              
711             # Fail if name or challonge_username or email is not provided:
712             unless((defined $args->{name}) || (defined $args->{challonge_username}) ||
713             defined $args->{email})
714             {
715             print STDERR "Error: Name, email or Challonge username are required to
716             create a new participant.\n";
717             return undef;
718             }
719              
720             # Check the arguments and values are valid:
721             return undef unless(WWW::Challonge::Participant::__args_are_valid($args));
722              
723             # Add in the API key and convert to a POST request:
724             my $params = { api_key => $key, participant => $args };
725              
726             # Now we have all the arguments validated, send the POST request:
727             $client->POST("/tournaments/$url/participants.json", to_json($params),
728             { "Content-Type" => 'application/json' });
729              
730             # Check if it was successful:
731             if($client->responseCode > 300)
732             {
733             my $errors = from_json($client->responseContent)->{errors};
734             for my $error(@{$errors})
735             {
736             print STDERR "Error: $error\n";
737             }
738             return undef;
739             }
740              
741             # If so, create an object and return it:
742             my $p = WWW::Challonge::Participant->new(from_json($client->responseContent),
743             $key, $client);
744             return $p;
745             }
746              
747             =head2 match_index
748              
749             Returns an arrayref of C objects for every
750             match in the tourney. The tournament must be in progress before this will
751             return anything useful.
752              
753             my $m = $t->match_index;
754             for my $match(@{$m})
755             {
756             ...
757              
758             =cut
759              
760             sub match_index
761             {
762             my $self = shift;
763              
764             # Do not operate on a dead tournament:
765             return __is_kill unless($self->{alive});
766              
767             # Get the key, REST client and url:
768             my $key = $self->{key};
769             my $client = $self->{client};
770             my $url = $self->{tournament}->{url};
771              
772             # Make the GET request:
773             $client->GET("/tournaments/$url/matches.json?api_key=$key");
774              
775             # Check if it was successful:
776             if($client->responseCode > 300)
777             {
778             my $errors = from_json($client->responseContent)->{errors};
779             for my $error(@{$errors})
780             {
781             print STDERR "Error: $error\n";
782             }
783             return undef;
784             }
785              
786             # If so, make an object for every participant:
787             my $matches = [];
788             for my $match(@{from_json($client->responseContent)})
789             {
790             push @{$matches}, WWW::Challonge::Match->new($match, $key,
791             $client);
792             }
793             return $matches;
794             }
795              
796             =head2 match_show
797              
798             Returns a single C object representing the match with
799             the given unique ID.
800              
801             my $m = $t->match_show(24279875);
802              
803             =cut
804              
805             sub match_show
806             {
807             my $self = shift;
808             my $match = shift;
809              
810             # Do not operate on a dead tournament:
811             return __is_kill unless($self->{alive});
812              
813             # Get the key, REST client and url:
814             my $key = $self->{key};
815             my $client = $self->{client};
816             my $url = $self->{tournament}->{url};
817              
818             # Make the GET request:
819             $client->GET("/tournaments/$url/matches/$match.json?api_key=$key");
820              
821             # Check if it was successful:
822             if($client->responseCode > 300)
823             {
824             my $errors = from_json($client->responseContent)->{errors};
825             for my $error(@{$errors})
826             {
827             print STDERR "Error: $error\n";
828             }
829             return undef;
830             }
831              
832             # If so, create an object and return it:
833             my $m = WWW::Challonge::Match->new(from_json($client->responseContent),
834             $key, $client);
835             return $m;
836             }
837              
838             =head2 __is_kill
839              
840             Returns an error explaining that the current tournament has been destroyed and
841             returns undef, used so a function doesn't attempt to operate on a tournament
842             that has been successfully destroyed.
843              
844             =cut
845              
846             sub __is_kill
847             {
848             print STDERR "Error: Tournament has been destroyed\n";
849             return undef;
850             }
851              
852             =head2 __args_are_valid
853              
854             Checks if the passed arguments and values are valid for creating or updating
855             a tournament.
856              
857             =cut
858              
859             sub __args_are_valid
860             {
861             my $args = shift;
862              
863             # The possible parameters, grouped together by the kind of input they take.
864             my %valid_args = (
865             string => [
866             "name",
867             "tournament_type",
868             "url",
869             "subdomain",
870             "description",
871             "game_name",
872             "ranked_by",
873             ],
874             integer => [
875             "swiss_rounds",
876             "signup_cap",
877             "check_in_duration",
878             ],
879             decimal => [
880             "pts_for_match_win",
881             "pts_for_match_tie",
882             "pts_for_game_win",
883             "pts_for_game_tie",
884             "pts_for_bye",
885             "rr_pts_for_match_win",
886             "rr_pts_for_match_tie",
887             "rr_pts_for_game_win",
888             "rr_pts_for_game_tie",
889             ],
890             bool => [
891             "open_signup",
892             "hold_third_place_match",
893             "accept_attachments",
894             "hide_forum",
895             "show_rounds",
896             "private",
897             "notify_users_when_matches_open",
898             "notify_users_when_the_tournament_ends",
899             "sequential_pairings",
900             ],
901             datetime => [
902             "start_at"
903             ],
904             );
905              
906             # Validate the inputs:
907             for my $arg(@{$valid_args{string}})
908             {
909             next unless(defined $args->{$arg});
910             # Most of the string-based arguments require individual validation
911             # based on what they are:
912             if($arg =~ /^name$/)
913             {
914             if(length $args->{$arg} > 60)
915             {
916             print STDERR "Error: Name '", $args->{$arg}, " is longer than ",
917             "60 characters";
918             return undef;
919             }
920             }
921             elsif($arg =~ /^tournament_type$/)
922             {
923             if($args->{$arg} !~ /^((single|double) elimination)|(round robin)|
924             (swiss)$/i)
925             {
926             print STDERR "Error: Value '", $args->{$arg}, "' is invalid ",
927             "for argument '", $arg, "'\n";
928             return undef;
929             }
930             }
931             elsif($arg =~ /^url$/)
932             {
933             if($args->{$arg} !~ /^[a-zA-Z0-9_]*$/)
934             {
935             print STDERR "Error: Value '", $args->{$arg}, "' is not a ",
936             "valid URL.\n";
937             return undef;
938             }
939             }
940             elsif($arg =~ /^ranked_by$/)
941             {
942             if($args->{$arg} !~ /^((match|game) wins)|
943             (points (scored|difference))|custom/i)
944             {
945             print STDERR "Error: Value '", $args->{$arg}, "' is invalid ",
946             "for argument '", $arg, "'\n";
947             return undef;
948             }
949             }
950             }
951             for my $arg(@{$valid_args{integer}})
952             {
953             next unless(defined $args->{$arg});
954             # Make sure the argument is an integer:
955             if($args->{$arg} !~ /^\d*$/)
956             {
957             print STDERR "Error: Value '", $args->{$arg}, "' is not a valid ",
958             "integer for argument '", $arg, "'\n";
959             return undef;
960             }
961             }
962             for my $arg(@{$valid_args{decimal}})
963             {
964             next unless(defined $args->{$arg});
965             # Make sure the argument is an integer or decimal:
966             if($args->{$arg} !~ /^\d*\.?\d*$/)
967             {
968             print STDERR "Error: Value '", $args->{$arg}, "' is not a valid ",
969             "decimal for argument '", $arg, "'\n";
970             return undef;
971             }
972             else
973             {
974             $args->{$arg} = sprintf("%.1f", $args->{$arg});
975             }
976             }
977             for my $arg(@{$valid_args{boolean}})
978             {
979             next unless(defined $args->{$arg});
980             # Make sure the argument is true or false:
981             if($args->{$arg} !~ /^(true|false)$/i)
982             {
983             print STDERR "Error: Value '", $args->{$arg}, "' is not a valid ",
984             "for argument '", $arg, "'. It should be 'true' or 'false'.\n";
985             return undef;
986             }
987             }
988             for my $arg(@{$valid_args{datetime}})
989             {
990             next unless(defined $args->{$arg});
991             # Make sure the argument is a valid datetime:
992             # if($args->{$arg} !~ /^$/)
993             # {
994             # print STDERR "Error: Value '", $args->{$arg}, "' is not a valid ",
995             # "for argument '", $arg, "'. It should be 'true' or 'false'.\n";
996             # return undef;
997             # }
998             }
999              
1000             # Finally, check if there are any unrecognised arguments, but just ignore
1001             # them instead of erroring out:
1002             my @accepted_inputs = (
1003             @{$valid_args{string}},
1004             @{$valid_args{integer}},
1005             @{$valid_args{decimal}},
1006             @{$valid_args{boolean}},
1007             @{$valid_args{datetime}}
1008             );
1009             my $is_valid = 0;
1010             for my $arg(keys %{$args})
1011             {
1012             for my $valid_arg(@accepted_inputs)
1013             {
1014             if($arg eq $valid_arg)
1015             {
1016             $is_valid = 1;
1017             last;
1018             }
1019             }
1020             print STDERR "Warning: Ignoring unknown argument '", $arg, "'\n"
1021             unless($is_valid);
1022             $is_valid = 0;
1023             }
1024             return 1;
1025             }
1026              
1027             =head1 AUTHOR
1028              
1029             Alex Kerr, C<< >>
1030              
1031             =head1 BUGS
1032              
1033             Please report any bugs or feature requests to C, or through
1034             the web interface at L. I will be notified, and then you'll
1035             automatically be notified of progress on your bug as I make changes.
1036              
1037             =head1 SUPPORT
1038              
1039             You can find documentation for this module with the perldoc command.
1040              
1041             perldoc WWW::Challonge::Tournament
1042              
1043             You can also look for information at:
1044              
1045             =over 4
1046              
1047             =item * RT: CPAN's request tracker (report bugs here)
1048              
1049             L
1050              
1051             =item * AnnoCPAN: Annotated CPAN documentation
1052              
1053             L
1054              
1055             =item * CPAN Ratings
1056              
1057             L
1058              
1059             =item * Search CPAN
1060              
1061             L
1062              
1063             =back
1064              
1065             =head1 SEE ALSO
1066              
1067             =over 4
1068              
1069             =item L
1070              
1071             =item L
1072              
1073             =item L
1074              
1075             =back
1076              
1077             =head1 ACKNOWLEDGEMENTS
1078              
1079             Everyone on the L team for making such a great
1080             service.
1081              
1082             =head1 LICENSE AND COPYRIGHT
1083              
1084             Copyright 2015 Alex Kerr.
1085              
1086             This program is free software; you can redistribute it and/or modify it
1087             under the terms of the the Artistic License (2.0). You may obtain a
1088             copy of the full license at:
1089              
1090             L
1091              
1092             Any use, modification, and distribution of the Standard or Modified
1093             Versions is governed by this Artistic License. By using, modifying or
1094             distributing the Package, you accept this license. Do not use, modify,
1095             or distribute the Package, if you do not accept this license.
1096              
1097             If your Modified Version has been derived from a Modified Version made
1098             by someone other than you, you are nevertheless required to ensure that
1099             your Modified Version complies with the requirements of this license.
1100              
1101             This license does not grant you the right to use any trademark, service
1102             mark, tradename, or logo of the Copyright Holder.
1103              
1104             This license includes the non-exclusive, worldwide, free-of-charge
1105             patent license to make, have made, use, offer to sell, sell, import and
1106             otherwise transfer the Package with respect to any patent claims
1107             licensable by the Copyright Holder that are necessarily infringed by the
1108             Package. If you institute patent litigation (including a cross-claim or
1109             counterclaim) against any party alleging that the Package constitutes
1110             direct or contributory patent infringement, then this Artistic License
1111             to you shall terminate on the date that such litigation is filed.
1112              
1113             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
1114             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
1115             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
1116             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
1117             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
1118             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
1119             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
1120             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1121              
1122              
1123             =cut
1124              
1125             1; # End of WWW::Challonge::Tournament