| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | # | 
| 2 |  |  |  |  |  |  | # Net::SMS::TextMagic  This module provides access to TextMagic SMS service | 
| 3 |  |  |  |  |  |  | # | 
| 4 |  |  |  |  |  |  | # Author: Matti Lattu | 
| 5 |  |  |  |  |  |  | # | 
| 6 |  |  |  |  |  |  | # Copyright (c) 2011 Matti Lattu. All rights reserved. | 
| 7 |  |  |  |  |  |  | # This program is free software; you can redistribute it and/or | 
| 8 |  |  |  |  |  |  | # modify it under the same terms as Perl itself. | 
| 9 |  |  |  |  |  |  | # | 
| 10 |  |  |  |  |  |  | # For TextMagic and its possible Copyright see http://www.textmagic.com/ | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | package Net::SMS::TextMagic; | 
| 13 |  |  |  |  |  |  |  | 
| 14 | 1 |  |  | 1 |  | 34149 | use strict; | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 56 |  | 
| 15 | 1 |  |  | 1 |  | 5 | use warnings; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 47 |  | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | our $VERSION = '1.00'; | 
| 18 |  |  |  |  |  |  |  | 
| 19 | 1 |  |  | 1 |  | 1209 | use JSON; | 
|  | 1 |  |  |  |  | 16849 |  | 
|  | 1 |  |  |  |  | 6 |  | 
| 20 | 1 |  |  | 1 |  | 1454 | use LWP::UserAgent; | 
|  | 1 |  |  |  |  | 50815 |  | 
|  | 1 |  |  |  |  | 41 |  | 
| 21 | 1 |  |  | 1 |  | 12 | use URI::Escape qw(uri_escape uri_escape_utf8); | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 87 |  | 
| 22 | 1 |  |  | 1 |  | 1075 | use Encode qw(encode decode); | 
|  | 1 |  |  |  |  | 11758 |  | 
|  | 1 |  |  |  |  | 1733 |  | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | =encoding utf8 | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | use Net::SMS::TextMagic; | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | my $sms = Net::SMS::TextMagic->new( USER => $username, API_ID => $api_id ); | 
| 31 |  |  |  |  |  |  | $sms->message_send(text=>'This is a test!', phone=>'35891911'); | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | TextMagic (http://www.textmagic.com) is a commercial service that allows its users to send | 
| 36 |  |  |  |  |  |  | SMS messages to anyone in the world. | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | Net::SMS::TextMagic provides OO methods that allow to send SMS messages through | 
| 39 |  |  |  |  |  |  | TextMagic service. The TextMagic HTTPS API is documented at | 
| 40 |  |  |  |  |  |  | L. This module implements all HTTPS API commands | 
| 41 |  |  |  |  |  |  | and return values. | 
| 42 |  |  |  |  |  |  | However, all command parameters and return values are not necessary mentioned or thorougly | 
| 43 |  |  |  |  |  |  | described in this document. Please consult the original API document for details. | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | Note that whether this software nor the author are related to TextMagic in any way. | 
| 46 |  |  |  |  |  |  |  | 
| 47 |  |  |  |  |  |  | =head1 METHODS | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | =over 4 | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | =item new | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  | Creates the TextMagic object. | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | Usage: | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | my $sms = Net::SMS::TextMagic->new( USER => $username, API_ID => $api_id ); | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | The complete list of arguments is: | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | B | 
| 62 |  |  |  |  |  |  | Your TextMagic username. Same as your username to TextMagic web service. | 
| 63 |  |  |  |  |  |  | Required. | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | B | 
| 66 |  |  |  |  |  |  | Your TextMagic API ID. The API ID is not your password to TextMagic | 
| 67 |  |  |  |  |  |  | web service. You can get your API ID from the | 
| 68 |  |  |  |  |  |  | TextMagic web service. Required. | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  | B | 
| 71 |  |  |  |  |  |  | TextMagic API URL. Defaults to https://www.textmagic.com/app/api. | 
| 72 |  |  |  |  |  |  |  | 
| 73 |  |  |  |  |  |  | B | 
| 74 |  |  |  |  |  |  | Name of the user agent you want to display to TextMagic service. | 
| 75 |  |  |  |  |  |  | Defaults to "Net::SMS::TextMagic" | 
| 76 |  |  |  |  |  |  |  | 
| 77 |  |  |  |  |  |  | B | 
| 78 |  |  |  |  |  |  | UserAgent timeout. Defaults to 10 seconds. | 
| 79 |  |  |  |  |  |  |  | 
| 80 |  |  |  |  |  |  | Returns Net::SMS::TextMagic object or false (in case USER or API_ID are missing). | 
| 81 |  |  |  |  |  |  |  | 
| 82 |  |  |  |  |  |  | =cut | 
| 83 |  |  |  |  |  |  |  | 
| 84 |  |  |  |  |  |  | sub new { | 
| 85 | 1 |  |  | 1 | 1 | 14 | my ($class, %params) = @_; | 
| 86 |  |  |  |  |  |  |  | 
| 87 | 1 |  |  |  |  | 3 | my $self = {}; | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | # Store TextMagic username (required) | 
| 90 |  |  |  |  |  |  |  | 
| 91 | 1 | 50 |  |  |  | 5 | if ($params{'USER'}) { | 
| 92 | 1 |  |  |  |  | 4 | $self->{'USER'} = $params{'USER'}; | 
| 93 |  |  |  |  |  |  | } | 
| 94 |  |  |  |  |  |  | else { | 
| 95 |  |  |  |  |  |  | # USER parameter is missing - return false | 
| 96 | 0 |  |  |  |  | 0 | return; | 
| 97 |  |  |  |  |  |  | } | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  | # Store TextMagic API ID (required) | 
| 100 |  |  |  |  |  |  |  | 
| 101 | 1 | 50 |  |  |  | 4 | if ($params{'API_ID'}) { | 
| 102 | 1 |  |  |  |  | 4 | $self->{'API_ID'} = $params{'API_ID'}; | 
| 103 |  |  |  |  |  |  | } | 
| 104 |  |  |  |  |  |  | else { | 
| 105 |  |  |  |  |  |  | # API_ID parameter is missing - return false | 
| 106 | 0 |  |  |  |  | 0 | return; | 
| 107 |  |  |  |  |  |  | } | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  | # Create LWP::UserAgent | 
| 110 | 1 |  |  |  |  | 10 | $self->{'UA'} = LWP::UserAgent->new; | 
| 111 |  |  |  |  |  |  |  | 
| 112 |  |  |  |  |  |  | # Set TextMagic API URL (optional) | 
| 113 |  |  |  |  |  |  |  | 
| 114 | 1 | 50 | 33 |  |  | 3735 | if (defined($params{'API_URL'}) and $params{'API_URL'} ne '') { | 
| 115 | 0 |  |  |  |  | 0 | $self->{'API_URL'} = $params{'API_URL'}; | 
| 116 |  |  |  |  |  |  | } | 
| 117 |  |  |  |  |  |  | else { | 
| 118 | 1 |  |  |  |  | 4 | $self->{'API_URL'} = 'https://www.textmagic.com/app/api'; | 
| 119 |  |  |  |  |  |  | } | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | # Set UserAgent string (optional) | 
| 122 |  |  |  |  |  |  |  | 
| 123 | 1 | 50 | 33 |  |  | 5 | if (defined($params{'UserAgent'}) and $params{'UserAgent'} ne '') { | 
| 124 | 0 |  |  |  |  | 0 | $self->{'UA'}->agent($params{'UserAgent'}); | 
| 125 |  |  |  |  |  |  | } | 
| 126 |  |  |  |  |  |  | else { | 
| 127 | 1 |  |  |  |  | 6 | $self->{'UA'}->agent('Net::SMS::TextMagic'); | 
| 128 |  |  |  |  |  |  | } | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | # Set UserAgent timeout (optional) | 
| 131 |  |  |  |  |  |  |  | 
| 132 | 1 | 50 | 33 |  |  | 70 | if (defined($params{'Timeout'}) and $params{'Timeout'} ne '') { | 
| 133 | 0 |  |  |  |  | 0 | $self->{'UA'}->timeout($params{'Timeout'}); | 
| 134 |  |  |  |  |  |  | } | 
| 135 |  |  |  |  |  |  | else { | 
| 136 |  |  |  |  |  |  | # Default timeout is 10 seconds | 
| 137 |  |  |  |  |  |  |  | 
| 138 | 1 |  |  |  |  | 7 | $self->{'UA'}->timeout(10); | 
| 139 |  |  |  |  |  |  | } | 
| 140 |  |  |  |  |  |  |  | 
| 141 |  |  |  |  |  |  | # Current error message | 
| 142 | 1 |  |  |  |  | 19 | $self->{'ERROR'} = undef; | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  | # Unprocessed error messages | 
| 145 | 1 |  |  |  |  | 4 | $self->{'ERROR_UNPROC'} = []; | 
| 146 |  |  |  |  |  |  |  | 
| 147 | 1 |  |  |  |  | 4 | bless($self, $class); | 
| 148 |  |  |  |  |  |  |  | 
| 149 | 1 |  |  |  |  | 6 | return $self; | 
| 150 |  |  |  |  |  |  | } | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  | =item message_send | 
| 153 |  |  |  |  |  |  |  | 
| 154 |  |  |  |  |  |  | Sends SMS message. Equals to HTTPS API command "send" but renamed in | 
| 155 |  |  |  |  |  |  | the module to avoid conflict with built-in send function. | 
| 156 |  |  |  |  |  |  |  | 
| 157 |  |  |  |  |  |  | Usage: | 
| 158 |  |  |  |  |  |  |  | 
| 159 |  |  |  |  |  |  | my %response = $sms->message_send(text=>'This is a test!', phone=>'35891911'); | 
| 160 |  |  |  |  |  |  | print "Sent message $response{'sent_text'} chopped in $response{'parts_count'} parts\n"; | 
| 161 |  |  |  |  |  |  |  | 
| 162 |  |  |  |  |  |  | The complete list of arguments is: | 
| 163 |  |  |  |  |  |  |  | 
| 164 |  |  |  |  |  |  | B | 
| 165 |  |  |  |  |  |  | Message text in Perl internal charset. Required. | 
| 166 |  |  |  |  |  |  |  | 
| 167 |  |  |  |  |  |  | B | 
| 168 |  |  |  |  |  |  | Phone number(s). The numbers are sent "as is". Currently the API supports up to | 
| 169 |  |  |  |  |  |  | 100 numbers separated by commas (,). Required. | 
| 170 |  |  |  |  |  |  |  | 
| 171 |  |  |  |  |  |  | B | 
| 172 |  |  |  |  |  |  | If set to true the message text is sent as UTF-8. Otherwise the text is sent | 
| 173 |  |  |  |  |  |  | in GSM 03.38 encoding. Defaults to true (UTF-8). | 
| 174 |  |  |  |  |  |  |  | 
| 175 |  |  |  |  |  |  | B, B, B | 
| 176 |  |  |  |  |  |  | See TextMagic HTTPS API documentation. | 
| 177 |  |  |  |  |  |  |  | 
| 178 |  |  |  |  |  |  | Returns a hash containing following keys: | 
| 179 |  |  |  |  |  |  |  | 
| 180 |  |  |  |  |  |  | B | 
| 181 |  |  |  |  |  |  | The text (in Perl internal charset) that was actually sent. | 
| 182 |  |  |  |  |  |  |  | 
| 183 |  |  |  |  |  |  | B | 
| 184 |  |  |  |  |  |  | The number of parts the message has. | 
| 185 |  |  |  |  |  |  |  | 
| 186 |  |  |  |  |  |  | B | 
| 187 |  |  |  |  |  |  | A hash containing pairs of numbers (keys) and message_ids (values) that were | 
| 188 |  |  |  |  |  |  | sent. | 
| 189 |  |  |  |  |  |  |  | 
| 190 |  |  |  |  |  |  | =cut | 
| 191 |  |  |  |  |  |  |  | 
| 192 |  |  |  |  |  |  | sub message_send { | 
| 193 | 0 |  |  | 0 | 1 |  | my ($class, %params) = @_; | 
| 194 |  |  |  |  |  |  |  | 
| 195 |  |  |  |  |  |  | # Check for required parameters | 
| 196 | 0 | 0 | 0 |  |  |  | if ((!$params{'text'}) or (!$params{'phone'})) { | 
| 197 | 0 |  |  |  |  |  | set_error($class, "method 'message_send' was called without required parameters"); | 
| 198 | 0 |  |  |  |  |  | return; | 
| 199 |  |  |  |  |  |  | } | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | # UNICODE defaults to true | 
| 202 | 0 | 0 |  |  |  |  | if (!defined($params{'unicode'})) { | 
| 203 | 0 |  |  |  |  |  | $params{'unicode'} = 1; | 
| 204 |  |  |  |  |  |  | } | 
| 205 |  |  |  |  |  |  |  | 
| 206 | 0 | 0 |  |  |  |  | if ($params{'unicode'}) { | 
| 207 |  |  |  |  |  |  | # Encode message as UTF8 | 
| 208 | 0 |  |  |  |  |  | $params{'text'} = uri_escape($params{'text'}); | 
| 209 |  |  |  |  |  |  | } | 
| 210 |  |  |  |  |  |  | else { | 
| 211 |  |  |  |  |  |  | # Encode message as GSM 03.38 | 
| 212 | 0 |  |  |  |  |  | $params{'text'} = encode("gsm0338", $params{'text'}); | 
| 213 | 0 |  |  |  |  |  | $params{'text'} = uri_escape($params{'text'}); | 
| 214 |  |  |  |  |  |  | } | 
| 215 |  |  |  |  |  |  |  | 
| 216 | 0 |  |  |  |  |  | my $r_json = contact_api($class, 'send', %params); | 
| 217 |  |  |  |  |  |  |  | 
| 218 | 0 | 0 |  |  |  |  | if (defined($r_json)) { | 
| 219 |  |  |  |  |  |  | # No errors | 
| 220 |  |  |  |  |  |  |  | 
| 221 | 0 |  |  |  |  |  | my %response = (); | 
| 222 |  |  |  |  |  |  |  | 
| 223 | 0 |  |  |  |  |  | $response{'sent_text'} = $r_json->{'sent_text'}; | 
| 224 |  |  |  |  |  |  |  | 
| 225 | 0 |  |  |  |  |  | $response{'parts_count'} = $r_json->{'parts_count'}; | 
| 226 |  |  |  |  |  |  |  | 
| 227 | 0 |  |  |  |  |  | while (my ($id, $number) = each %{$r_json->{"message_id"}} ) { | 
|  | 0 |  |  |  |  |  |  | 
| 228 | 0 |  |  |  |  |  | $response{'message_id'}{$number} = $id; | 
| 229 |  |  |  |  |  |  | } | 
| 230 |  |  |  |  |  |  |  | 
| 231 | 0 |  |  |  |  |  | return %response; | 
| 232 |  |  |  |  |  |  | } | 
| 233 |  |  |  |  |  |  | else { | 
| 234 |  |  |  |  |  |  | # Errors, we expect that error flag was raised in contact_api() | 
| 235 |  |  |  |  |  |  |  | 
| 236 | 0 |  |  |  |  |  | return; | 
| 237 |  |  |  |  |  |  | } | 
| 238 |  |  |  |  |  |  | } | 
| 239 |  |  |  |  |  |  |  | 
| 240 |  |  |  |  |  |  | =item account | 
| 241 |  |  |  |  |  |  |  | 
| 242 |  |  |  |  |  |  | Get the current SMS credit balance. | 
| 243 |  |  |  |  |  |  |  | 
| 244 |  |  |  |  |  |  | Usage: | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  | my %response = $sms->account(); | 
| 247 |  |  |  |  |  |  | print "Your balance is $response{'balance'}\n"; | 
| 248 |  |  |  |  |  |  |  | 
| 249 |  |  |  |  |  |  | Returns a hash containing following key: | 
| 250 |  |  |  |  |  |  |  | 
| 251 |  |  |  |  |  |  | B | 
| 252 |  |  |  |  |  |  | The amount of available SMS credits on your account. | 
| 253 |  |  |  |  |  |  |  | 
| 254 |  |  |  |  |  |  | =cut | 
| 255 |  |  |  |  |  |  |  | 
| 256 |  |  |  |  |  |  | sub account { | 
| 257 | 0 |  |  | 0 | 1 |  | my ($class) = @_; | 
| 258 |  |  |  |  |  |  |  | 
| 259 | 0 |  |  |  |  |  | my $r_json = contact_api($class, 'account'); | 
| 260 |  |  |  |  |  |  |  | 
| 261 | 0 | 0 |  |  |  |  | if (defined($r_json)) { | 
| 262 |  |  |  |  |  |  | # No errors | 
| 263 |  |  |  |  |  |  |  | 
| 264 | 0 |  |  |  |  |  | my %response = (); | 
| 265 |  |  |  |  |  |  |  | 
| 266 | 0 |  |  |  |  |  | $response{'balance'} = $r_json->{'balance'}; | 
| 267 |  |  |  |  |  |  |  | 
| 268 | 0 |  |  |  |  |  | return %response; | 
| 269 |  |  |  |  |  |  | } | 
| 270 |  |  |  |  |  |  | else { | 
| 271 |  |  |  |  |  |  | # Errors, we expect that error flag was raised in contact_api() | 
| 272 |  |  |  |  |  |  |  | 
| 273 | 0 |  |  |  |  |  | return; | 
| 274 |  |  |  |  |  |  | } | 
| 275 |  |  |  |  |  |  | } | 
| 276 |  |  |  |  |  |  |  | 
| 277 |  |  |  |  |  |  | =item message_status | 
| 278 |  |  |  |  |  |  |  | 
| 279 |  |  |  |  |  |  | This method allows you to retrieve the delivery status of any SMS you have | 
| 280 |  |  |  |  |  |  | already sent. The message ID is returned by message_send command. | 
| 281 |  |  |  |  |  |  |  | 
| 282 |  |  |  |  |  |  | Usage: | 
| 283 |  |  |  |  |  |  |  | 
| 284 |  |  |  |  |  |  | my $this_id = 123456; | 
| 285 |  |  |  |  |  |  | my %response = $sms->message_status($this_id); | 
| 286 |  |  |  |  |  |  | print 'Message text was '.$response{$this_id}{'text'}."\n"; | 
| 287 |  |  |  |  |  |  | print 'The cost was '.$response{$this_id}{'credits_cost'}." credits\n"; | 
| 288 |  |  |  |  |  |  |  | 
| 289 |  |  |  |  |  |  | The only parameter is a string containing message ID or several IDs | 
| 290 |  |  |  |  |  |  | separated by commas and without spaces (e.g. "8624389,8624390,8624391"). | 
| 291 |  |  |  |  |  |  | Up to 100 IDs can be retrieved with a single command. | 
| 292 |  |  |  |  |  |  |  | 
| 293 |  |  |  |  |  |  | Returns a two-level hash containing status of message IDs. Each ID has following | 
| 294 |  |  |  |  |  |  | fields: | 
| 295 |  |  |  |  |  |  |  | 
| 296 |  |  |  |  |  |  | B | 
| 297 |  |  |  |  |  |  | SMS text sent. | 
| 298 |  |  |  |  |  |  |  | 
| 299 |  |  |  |  |  |  | B | 
| 300 |  |  |  |  |  |  | The current status of the message. The status codes are explained at | 
| 301 |  |  |  |  |  |  | L. | 
| 302 |  |  |  |  |  |  |  | 
| 303 |  |  |  |  |  |  | B | 
| 304 |  |  |  |  |  |  | The time TextMagic sent the message. Unix timestamp. | 
| 305 |  |  |  |  |  |  |  | 
| 306 |  |  |  |  |  |  | B | 
| 307 |  |  |  |  |  |  | See API documentation for details. | 
| 308 |  |  |  |  |  |  |  | 
| 309 |  |  |  |  |  |  | B | 
| 310 |  |  |  |  |  |  | Cost of the message in SMS credits. Set when message is delivered. | 
| 311 |  |  |  |  |  |  |  | 
| 312 |  |  |  |  |  |  | B | 
| 313 |  |  |  |  |  |  | The time your message achieves final status, returned by the mobile operator. | 
| 314 |  |  |  |  |  |  | Unix timestamp. | 
| 315 |  |  |  |  |  |  |  | 
| 316 |  |  |  |  |  |  | =cut | 
| 317 |  |  |  |  |  |  |  | 
| 318 |  |  |  |  |  |  | sub message_status { | 
| 319 | 0 |  |  | 0 | 1 |  | my ($class, $ids) = @_; | 
| 320 |  |  |  |  |  |  |  | 
| 321 |  |  |  |  |  |  | # Check for required parameters | 
| 322 | 0 | 0 |  |  |  |  | if (!$ids) { | 
| 323 | 0 |  |  |  |  |  | set_error($class, "method 'message_status' was called without parameters"); | 
| 324 | 0 |  |  |  |  |  | return; | 
| 325 |  |  |  |  |  |  | } | 
| 326 |  |  |  |  |  |  |  | 
| 327 | 0 |  |  |  |  |  | my %params = ('ids' => $ids); | 
| 328 |  |  |  |  |  |  |  | 
| 329 | 0 |  |  |  |  |  | my $r_json = contact_api($class, 'message_status', %params); | 
| 330 |  |  |  |  |  |  |  | 
| 331 | 0 | 0 |  |  |  |  | if (defined($r_json)) { | 
| 332 |  |  |  |  |  |  | # No errors | 
| 333 |  |  |  |  |  |  |  | 
| 334 | 0 |  |  |  |  |  | my %response = (); | 
| 335 |  |  |  |  |  |  |  | 
| 336 | 0 |  |  |  |  |  | foreach my $this_id (keys %{$r_json}) { | 
|  | 0 |  |  |  |  |  |  | 
| 337 | 0 |  |  |  |  |  | $response{$this_id} = (); | 
| 338 | 0 |  |  |  |  |  | $response{$this_id}{'text'} = encode("utf8", $r_json->{$this_id}->{'text'}); | 
| 339 | 0 |  |  |  |  |  | $response{$this_id}{'status'} = $r_json->{$this_id}->{'status'}; | 
| 340 | 0 |  |  |  |  |  | $response{$this_id}{'created_time'} = $r_json->{$this_id}->{'created_time'}; | 
| 341 | 0 |  |  |  |  |  | $response{$this_id}{'reply_number'} = $r_json->{$this_id}->{'reply_number'}; | 
| 342 | 0 |  |  |  |  |  | $response{$this_id}{'credits_cost'} = $r_json->{$this_id}->{'credits_cost'}; | 
| 343 | 0 |  |  |  |  |  | $response{$this_id}{'completed_time'} = $r_json->{$this_id}->{'completed_time'}; | 
| 344 |  |  |  |  |  |  | } | 
| 345 |  |  |  |  |  |  |  | 
| 346 | 0 |  |  |  |  |  | return %response; | 
| 347 |  |  |  |  |  |  | } | 
| 348 |  |  |  |  |  |  | else { | 
| 349 |  |  |  |  |  |  | # Errors, we expect that error flag was raised in contact_api() | 
| 350 |  |  |  |  |  |  |  | 
| 351 | 0 |  |  |  |  |  | return; | 
| 352 |  |  |  |  |  |  | } | 
| 353 |  |  |  |  |  |  | } | 
| 354 |  |  |  |  |  |  |  | 
| 355 |  |  |  |  |  |  | =item receive | 
| 356 |  |  |  |  |  |  |  | 
| 357 |  |  |  |  |  |  | This method retrieves the incoming SMS messages from the server. | 
| 358 |  |  |  |  |  |  | The server is limited to returning a maximum of 100 messages for | 
| 359 |  |  |  |  |  |  | each request. Please use last_retrieved_id parameter to page through | 
| 360 |  |  |  |  |  |  | your inbox. | 
| 361 |  |  |  |  |  |  |  | 
| 362 |  |  |  |  |  |  | The only optional parameter is B. The server will | 
| 363 |  |  |  |  |  |  | only return messages with identifiers greater than B. | 
| 364 |  |  |  |  |  |  | The default value is 0 which fetches up to the first 100 replies from | 
| 365 |  |  |  |  |  |  | your inbox. | 
| 366 |  |  |  |  |  |  |  | 
| 367 |  |  |  |  |  |  | Returns a hash containing following keys: | 
| 368 |  |  |  |  |  |  |  | 
| 369 |  |  |  |  |  |  | B | 
| 370 |  |  |  |  |  |  | The number of messages with identifiers greater than B | 
| 371 |  |  |  |  |  |  | remaining unreturned due to the limit on returned messages per request. | 
| 372 |  |  |  |  |  |  |  | 
| 373 |  |  |  |  |  |  | B | 
| 374 |  |  |  |  |  |  | Number of messages in the current B hash. | 
| 375 |  |  |  |  |  |  |  | 
| 376 |  |  |  |  |  |  | B | 
| 377 |  |  |  |  |  |  | An array containing all messages. Each object in the array is a hash | 
| 378 |  |  |  |  |  |  | with following keys: | 
| 379 |  |  |  |  |  |  |  | 
| 380 |  |  |  |  |  |  | =over 4 | 
| 381 |  |  |  |  |  |  |  | 
| 382 |  |  |  |  |  |  | B | 
| 383 |  |  |  |  |  |  | The identifier of the incoming message. | 
| 384 |  |  |  |  |  |  |  | 
| 385 |  |  |  |  |  |  | B | 
| 386 |  |  |  |  |  |  | The sender's phone number. | 
| 387 |  |  |  |  |  |  |  | 
| 388 |  |  |  |  |  |  | B | 
| 389 |  |  |  |  |  |  | The message's reception time expressed in Unix time format. | 
| 390 |  |  |  |  |  |  |  | 
| 391 |  |  |  |  |  |  | B | 
| 392 |  |  |  |  |  |  | The message text. | 
| 393 |  |  |  |  |  |  |  | 
| 394 |  |  |  |  |  |  | =back | 
| 395 |  |  |  |  |  |  |  | 
| 396 |  |  |  |  |  |  | =cut | 
| 397 |  |  |  |  |  |  |  | 
| 398 |  |  |  |  |  |  | sub receive { | 
| 399 | 0 |  |  | 0 | 1 |  | my ($class,$lrid) = @_; | 
| 400 |  |  |  |  |  |  |  | 
| 401 | 0 | 0 |  |  |  |  | if (!defined($lrid)) { | 
| 402 |  |  |  |  |  |  | # Default value for last_retrieved_id | 
| 403 | 0 |  |  |  |  |  | $lrid = 0; | 
| 404 |  |  |  |  |  |  | } | 
| 405 |  |  |  |  |  |  |  | 
| 406 | 0 |  |  |  |  |  | my %params = ('last_retrieved_id' => $lrid); | 
| 407 |  |  |  |  |  |  |  | 
| 408 | 0 |  |  |  |  |  | my $r_json = contact_api($class, 'receive', %params); | 
| 409 |  |  |  |  |  |  |  | 
| 410 | 0 | 0 |  |  |  |  | if (defined($r_json)) { | 
| 411 |  |  |  |  |  |  | # No errors | 
| 412 |  |  |  |  |  |  |  | 
| 413 | 0 |  |  |  |  |  | my %response = (); | 
| 414 |  |  |  |  |  |  |  | 
| 415 | 0 |  |  |  |  |  | $response{'unread'} = $r_json->{'unread'}; | 
| 416 | 0 |  |  |  |  |  | $response{'messages_count'} = scalar(@{$r_json->{'messages'}}); | 
|  | 0 |  |  |  |  |  |  | 
| 417 |  |  |  |  |  |  |  | 
| 418 | 0 |  |  |  |  |  | print "messages count: ".scalar(@{$r_json->{'messages'}})."\n"; | 
|  | 0 |  |  |  |  |  |  | 
| 419 |  |  |  |  |  |  |  | 
| 420 | 0 |  |  |  |  |  | for (my $i=0; $i < scalar(@{$r_json->{'messages'}}); $i++) { | 
|  | 0 |  |  |  |  |  |  | 
| 421 | 0 |  |  |  |  |  | my %this_msg_data = (); | 
| 422 | 0 |  |  |  |  |  | $this_msg_data{'message_id'} = @{$r_json->{'messages'}}[$i]->{'message_id'}; | 
|  | 0 |  |  |  |  |  |  | 
| 423 | 0 |  |  |  |  |  | $this_msg_data{'from'} = @{$r_json->{'messages'}}[$i]->{'from'}; | 
|  | 0 |  |  |  |  |  |  | 
| 424 | 0 |  |  |  |  |  | $this_msg_data{'timestamp'} = @{$r_json->{'messages'}}[$i]->{'timestamp'}; | 
|  | 0 |  |  |  |  |  |  | 
| 425 | 0 |  |  |  |  |  | $this_msg_data{'text'} = encode("utf8", @{$r_json->{'messages'}}[$i]->{'text'}); | 
|  | 0 |  |  |  |  |  |  | 
| 426 | 0 |  |  |  |  |  | push(@{$response{'messages'}}, {%this_msg_data}); | 
|  | 0 |  |  |  |  |  |  | 
| 427 |  |  |  |  |  |  | } | 
| 428 |  |  |  |  |  |  |  | 
| 429 | 0 |  |  |  |  |  | return %response; | 
| 430 |  |  |  |  |  |  | } | 
| 431 |  |  |  |  |  |  | else { | 
| 432 |  |  |  |  |  |  | # Errors, we expect that error flag was raised in contact_api() | 
| 433 |  |  |  |  |  |  |  | 
| 434 | 0 |  |  |  |  |  | return; | 
| 435 |  |  |  |  |  |  | } | 
| 436 |  |  |  |  |  |  | } | 
| 437 |  |  |  |  |  |  |  | 
| 438 |  |  |  |  |  |  | =item delete_reply | 
| 439 |  |  |  |  |  |  |  | 
| 440 |  |  |  |  |  |  | This command helps you to delete any incoming SMS messages from the server. | 
| 441 |  |  |  |  |  |  |  | 
| 442 |  |  |  |  |  |  | Usage: | 
| 443 |  |  |  |  |  |  |  | 
| 444 |  |  |  |  |  |  | my @response = $sms->delete_reply('123456,123457,123458'); | 
| 445 |  |  |  |  |  |  | print "Following messages were deleted: ".join(', ', @response)."\n"; | 
| 446 |  |  |  |  |  |  |  | 
| 447 |  |  |  |  |  |  | The only required parameter is a string containing message IDs to be deleted. | 
| 448 |  |  |  |  |  |  | The IDs should be separated with commas without spaces. Up to 100 messages | 
| 449 |  |  |  |  |  |  | can be deleted with single command. | 
| 450 |  |  |  |  |  |  |  | 
| 451 |  |  |  |  |  |  | Returns an array containing message IDs that were deleted. | 
| 452 |  |  |  |  |  |  |  | 
| 453 |  |  |  |  |  |  | =cut | 
| 454 |  |  |  |  |  |  |  | 
| 455 |  |  |  |  |  |  | sub delete_reply { | 
| 456 | 0 |  |  | 0 | 1 |  | my ($class, $delids) = @_; | 
| 457 |  |  |  |  |  |  |  | 
| 458 | 0 | 0 |  |  |  |  | if (!defined($delids)) { | 
| 459 | 0 |  |  |  |  |  | set_error($class, "method 'delete_reply' was called without parameters"); | 
| 460 | 0 |  |  |  |  |  | return; | 
| 461 |  |  |  |  |  |  | } | 
| 462 |  |  |  |  |  |  |  | 
| 463 | 0 |  |  |  |  |  | my %params = ('ids' => $delids); | 
| 464 |  |  |  |  |  |  |  | 
| 465 | 0 |  |  |  |  |  | my $r_json = contact_api($class, 'delete_reply', %params); | 
| 466 |  |  |  |  |  |  |  | 
| 467 | 0 | 0 |  |  |  |  | if (defined($r_json)) { | 
| 468 |  |  |  |  |  |  | # No errors | 
| 469 |  |  |  |  |  |  |  | 
| 470 | 0 |  |  |  |  |  | return @{$r_json->{'deleted'}}; | 
|  | 0 |  |  |  |  |  |  | 
| 471 |  |  |  |  |  |  | } | 
| 472 |  |  |  |  |  |  | else { | 
| 473 |  |  |  |  |  |  | # Errors, we expect that error flag was raised in contact_api() | 
| 474 |  |  |  |  |  |  |  | 
| 475 | 0 |  |  |  |  |  | return; | 
| 476 |  |  |  |  |  |  | } | 
| 477 |  |  |  |  |  |  | } | 
| 478 |  |  |  |  |  |  |  | 
| 479 |  |  |  |  |  |  | =item check_number | 
| 480 |  |  |  |  |  |  |  | 
| 481 |  |  |  |  |  |  | This command helps you to validate a phone number's format and to check a | 
| 482 |  |  |  |  |  |  | message's price to its destination. | 
| 483 |  |  |  |  |  |  |  | 
| 484 |  |  |  |  |  |  | Usage: | 
| 485 |  |  |  |  |  |  |  | 
| 486 |  |  |  |  |  |  | my %response = $sms->check_number('35891911,35891912'); | 
| 487 |  |  |  |  |  |  |  | 
| 488 |  |  |  |  |  |  | foreach my $this_number (keys %response) { | 
| 489 |  |  |  |  |  |  | print "Number $this_number is in ". | 
| 490 |  |  |  |  |  |  | $response{$this_number}{'country'}. | 
| 491 |  |  |  |  |  |  | 'and the SMS cost is '. | 
| 492 |  |  |  |  |  |  | $response{$this_number}{'price'}. | 
| 493 |  |  |  |  |  |  | "credits.\n"; | 
| 494 |  |  |  |  |  |  | } | 
| 495 |  |  |  |  |  |  |  | 
| 496 |  |  |  |  |  |  | The only required parameter is a string containing phone numbers to be checked. | 
| 497 |  |  |  |  |  |  | The numbers should be separated with commas without spaces. The TextMagic HTTPS | 
| 498 |  |  |  |  |  |  | API documentation does not specify the maximum number of phone numbers that | 
| 499 |  |  |  |  |  |  | can be checked with a single command. | 
| 500 |  |  |  |  |  |  |  | 
| 501 |  |  |  |  |  |  | Returns a two-level hash containing status of numbers. Each number has following | 
| 502 |  |  |  |  |  |  | fields: | 
| 503 |  |  |  |  |  |  |  | 
| 504 |  |  |  |  |  |  | B | 
| 505 |  |  |  |  |  |  | The cost in SMS credits of sending a single message to the number. | 
| 506 |  |  |  |  |  |  |  | 
| 507 |  |  |  |  |  |  | B | 
| 508 |  |  |  |  |  |  | The number's country code. A full list of country codes can be found at | 
| 509 |  |  |  |  |  |  | L. | 
| 510 |  |  |  |  |  |  |  | 
| 511 |  |  |  |  |  |  | =cut | 
| 512 |  |  |  |  |  |  |  | 
| 513 |  |  |  |  |  |  | sub check_number { | 
| 514 | 0 |  |  | 0 | 1 |  | my ($class, $numbers) = @_; | 
| 515 |  |  |  |  |  |  |  | 
| 516 | 0 | 0 |  |  |  |  | if (!defined($numbers)) { | 
| 517 | 0 |  |  |  |  |  | set_error($class, "method 'check_number' was called without parameters"); | 
| 518 | 0 |  |  |  |  |  | return; | 
| 519 |  |  |  |  |  |  | } | 
| 520 |  |  |  |  |  |  |  | 
| 521 | 0 |  |  |  |  |  | my %params = ('phone' => $numbers); | 
| 522 |  |  |  |  |  |  |  | 
| 523 | 0 |  |  |  |  |  | my $r_json = contact_api($class, 'check_number', %params); | 
| 524 |  |  |  |  |  |  |  | 
| 525 | 0 | 0 |  |  |  |  | if (defined($r_json)) { | 
| 526 |  |  |  |  |  |  | # No errors | 
| 527 |  |  |  |  |  |  |  | 
| 528 | 0 |  |  |  |  |  | my %response = (); | 
| 529 |  |  |  |  |  |  |  | 
| 530 | 0 |  |  |  |  |  | foreach my $this_number (keys %{$r_json}) { | 
|  | 0 |  |  |  |  |  |  | 
| 531 | 0 |  |  |  |  |  | $response{$this_number}{'price'} = $r_json->{$this_number}->{'price'}; | 
| 532 | 0 |  |  |  |  |  | $response{$this_number}{'country'} = $r_json->{$this_number}->{'country'}; | 
| 533 |  |  |  |  |  |  | } | 
| 534 |  |  |  |  |  |  |  | 
| 535 | 0 |  |  |  |  |  | return %response; | 
| 536 |  |  |  |  |  |  | } | 
| 537 |  |  |  |  |  |  | else { | 
| 538 |  |  |  |  |  |  | # Errors, we expect that error flag was raised in contact_api() | 
| 539 |  |  |  |  |  |  |  | 
| 540 | 0 |  |  |  |  |  | return; | 
| 541 |  |  |  |  |  |  | } | 
| 542 |  |  |  |  |  |  | } | 
| 543 |  |  |  |  |  |  |  | 
| 544 |  |  |  |  |  |  | =item contact_api | 
| 545 |  |  |  |  |  |  |  | 
| 546 |  |  |  |  |  |  | Contacts TextMagic API. This in mainly for internal use, but can be used | 
| 547 |  |  |  |  |  |  | to contact TextMagic API directly. | 
| 548 |  |  |  |  |  |  |  | 
| 549 |  |  |  |  |  |  | Usage: | 
| 550 |  |  |  |  |  |  |  | 
| 551 |  |  |  |  |  |  | my $r_json = $sms->contact_api('some_api_command', %parameters); | 
| 552 |  |  |  |  |  |  |  | 
| 553 |  |  |  |  |  |  | Parameters: | 
| 554 |  |  |  |  |  |  | - a string containing TextMagic HTTPS API command | 
| 555 |  |  |  |  |  |  | - a hash containing command parameters | 
| 556 |  |  |  |  |  |  |  | 
| 557 |  |  |  |  |  |  | Returns a JSON object containing the result. | 
| 558 |  |  |  |  |  |  |  | 
| 559 |  |  |  |  |  |  | =cut | 
| 560 |  |  |  |  |  |  |  | 
| 561 |  |  |  |  |  |  | sub contact_api { | 
| 562 | 0 |  |  | 0 | 1 |  | my ($class, $cmd, %params) = @_; | 
| 563 |  |  |  |  |  |  |  | 
| 564 | 0 |  |  |  |  |  | $params{'cmd'} = $cmd; | 
| 565 | 0 |  |  |  |  |  | $params{'username'} = $class->{'USER'}; | 
| 566 | 0 |  |  |  |  |  | $params{'password'} = $class->{'API_ID'}; | 
| 567 |  |  |  |  |  |  |  | 
| 568 | 0 |  |  |  |  |  | my $response = $class->{'UA'}->post($class->{'API_URL'}, Content=>\%params); | 
| 569 |  |  |  |  |  |  |  | 
| 570 | 0 | 0 |  |  |  |  | if ($response->is_success) { | 
| 571 |  |  |  |  |  |  | # For debugging | 
| 572 |  |  |  |  |  |  | # print "---JSON begins:\n".$response->decoded_content."\n---JSON ends\n"; | 
| 573 | 0 |  |  |  |  |  | my $json_obj = decode_json($response->decoded_content); | 
| 574 | 0 | 0 |  |  |  |  | if ($json_obj->{'error_code'}) { | 
| 575 |  |  |  |  |  |  | # API error, set error message | 
| 576 |  |  |  |  |  |  |  | 
| 577 | 0 |  |  |  |  |  | set_error($class, 'API error #'.$json_obj->{'error_code'}.': '.$json_obj->{'error_message'}); | 
| 578 | 0 |  |  |  |  |  | return; | 
| 579 |  |  |  |  |  |  | } | 
| 580 |  |  |  |  |  |  | else { | 
| 581 |  |  |  |  |  |  | # API ok, return JSON object | 
| 582 |  |  |  |  |  |  |  | 
| 583 | 0 |  |  |  |  |  | return $json_obj; | 
| 584 |  |  |  |  |  |  | } | 
| 585 |  |  |  |  |  |  | } | 
| 586 |  |  |  |  |  |  | else { | 
| 587 |  |  |  |  |  |  | # HTTP POST failed | 
| 588 | 0 |  |  |  |  |  | set_error($class, "HTTP POST failed: ".$response->status_line); | 
| 589 | 0 |  |  |  |  |  | return; | 
| 590 |  |  |  |  |  |  | } | 
| 591 |  |  |  |  |  |  | } | 
| 592 |  |  |  |  |  |  |  | 
| 593 |  |  |  |  |  |  | =item set_error | 
| 594 |  |  |  |  |  |  |  | 
| 595 |  |  |  |  |  |  | Sets Net::SMS::TextMagic error code. Mainly for internal use. | 
| 596 |  |  |  |  |  |  |  | 
| 597 |  |  |  |  |  |  | If there is already an unprocessed error message, this message | 
| 598 |  |  |  |  |  |  | is appended to the unprocessed error array. The array can be read | 
| 599 |  |  |  |  |  |  | and emptied with get_unprocessed_errors(). | 
| 600 |  |  |  |  |  |  |  | 
| 601 |  |  |  |  |  |  | Usage: | 
| 602 |  |  |  |  |  |  |  | 
| 603 |  |  |  |  |  |  | $sms->set_error('Out of credit'); | 
| 604 |  |  |  |  |  |  |  | 
| 605 |  |  |  |  |  |  | =cut | 
| 606 |  |  |  |  |  |  |  | 
| 607 |  |  |  |  |  |  | sub set_error { | 
| 608 | 0 |  |  | 0 | 1 |  | my ($class, $errormsg) = @_; | 
| 609 |  |  |  |  |  |  |  | 
| 610 |  |  |  |  |  |  | # If there are alredy current error, add error to error buffer | 
| 611 | 0 | 0 |  |  |  |  | if ($class->{'ERROR'}) { | 
| 612 | 0 |  |  |  |  |  | push(@{$class->{'ERROR_UNPROC'}}, $class->{'ERROR'}); | 
|  | 0 |  |  |  |  |  |  | 
| 613 |  |  |  |  |  |  | } | 
| 614 |  |  |  |  |  |  |  | 
| 615 | 0 |  |  |  |  |  | $class->{'ERROR'} = $errormsg; | 
| 616 |  |  |  |  |  |  |  | 
| 617 | 0 |  |  |  |  |  | return 1; | 
| 618 |  |  |  |  |  |  | } | 
| 619 |  |  |  |  |  |  |  | 
| 620 |  |  |  |  |  |  | =item get_error | 
| 621 |  |  |  |  |  |  |  | 
| 622 |  |  |  |  |  |  | Gets and clears Net::SMS::TextMagic error code. This does not affect the | 
| 623 |  |  |  |  |  |  | array of unprocessed error messages (see get_unprocessed_errors()). | 
| 624 |  |  |  |  |  |  |  | 
| 625 |  |  |  |  |  |  | Usage: | 
| 626 |  |  |  |  |  |  |  | 
| 627 |  |  |  |  |  |  | my %response = $sms->message_send('phone' => '123456', 'text' => 'Howdy!'); | 
| 628 |  |  |  |  |  |  | if ($sms->if_error()) { | 
| 629 |  |  |  |  |  |  | my $errormsg = $sms->get_error(); | 
| 630 |  |  |  |  |  |  | if ($errormsg) { | 
| 631 |  |  |  |  |  |  | print "Dough! $errormsg\n"; | 
| 632 |  |  |  |  |  |  | } | 
| 633 |  |  |  |  |  |  | } | 
| 634 |  |  |  |  |  |  |  | 
| 635 |  |  |  |  |  |  | No parameters. Returns a error string if error flag is up. If no error message is | 
| 636 |  |  |  |  |  |  | present returns undef. | 
| 637 |  |  |  |  |  |  |  | 
| 638 |  |  |  |  |  |  | =cut | 
| 639 |  |  |  |  |  |  |  | 
| 640 |  |  |  |  |  |  | sub get_error { | 
| 641 | 0 |  |  | 0 | 1 |  | my ($class) = @_; | 
| 642 |  |  |  |  |  |  |  | 
| 643 | 0 |  |  |  |  |  | my $errormsg = $class->{'ERROR'}; | 
| 644 | 0 |  |  |  |  |  | $class->{'ERROR'} = undef; | 
| 645 |  |  |  |  |  |  |  | 
| 646 | 0 |  |  |  |  |  | return $errormsg; | 
| 647 |  |  |  |  |  |  | } | 
| 648 |  |  |  |  |  |  |  | 
| 649 |  |  |  |  |  |  | =item if_error | 
| 650 |  |  |  |  |  |  |  | 
| 651 |  |  |  |  |  |  | Returns true if there is a pending error code (see get_error()). | 
| 652 |  |  |  |  |  |  | Returns false if no error flag is set. | 
| 653 |  |  |  |  |  |  |  | 
| 654 |  |  |  |  |  |  | Usage: | 
| 655 |  |  |  |  |  |  |  | 
| 656 |  |  |  |  |  |  | if ($sms->if_error()) { | 
| 657 |  |  |  |  |  |  | print STDERR "SMS error: ".$sms->get_error()."\n"; | 
| 658 |  |  |  |  |  |  | } | 
| 659 |  |  |  |  |  |  |  | 
| 660 |  |  |  |  |  |  | =cut | 
| 661 |  |  |  |  |  |  |  | 
| 662 |  |  |  |  |  |  | sub if_error { | 
| 663 | 0 |  |  | 0 | 1 |  | my ($class) = @_; | 
| 664 |  |  |  |  |  |  |  | 
| 665 | 0 | 0 |  |  |  |  | if ($class->{'ERROR'}) { | 
| 666 | 0 |  |  |  |  |  | return 1; | 
| 667 |  |  |  |  |  |  | } | 
| 668 |  |  |  |  |  |  | else { | 
| 669 | 0 |  |  |  |  |  | return; | 
| 670 |  |  |  |  |  |  | } | 
| 671 |  |  |  |  |  |  | } | 
| 672 |  |  |  |  |  |  |  | 
| 673 |  |  |  |  |  |  | =item get_unprocessed_errors | 
| 674 |  |  |  |  |  |  |  | 
| 675 |  |  |  |  |  |  | Returns and flushes the array of unprocessed errors. See set_error(). | 
| 676 |  |  |  |  |  |  |  | 
| 677 |  |  |  |  |  |  | =cut | 
| 678 |  |  |  |  |  |  |  | 
| 679 |  |  |  |  |  |  | sub get_unprocessed_errors { | 
| 680 | 0 |  |  | 0 | 1 |  | my ($class) = @_; | 
| 681 |  |  |  |  |  |  |  | 
| 682 | 0 |  |  |  |  |  | my @errors = @{$class->{'ERRORS_UNPROC'}}; | 
|  | 0 |  |  |  |  |  |  | 
| 683 |  |  |  |  |  |  |  | 
| 684 | 0 |  |  |  |  |  | $class->{'ERRORS_UNPROC'} = []; | 
| 685 |  |  |  |  |  |  |  | 
| 686 | 0 |  |  |  |  |  | return @errors; | 
| 687 |  |  |  |  |  |  | } | 
| 688 |  |  |  |  |  |  |  | 
| 689 |  |  |  |  |  |  | =item if_unprocessed_errors | 
| 690 |  |  |  |  |  |  |  | 
| 691 |  |  |  |  |  |  | Returns a number of items in the array of unprocessed errors. If | 
| 692 |  |  |  |  |  |  | there are no errors returns undef (false). | 
| 693 |  |  |  |  |  |  |  | 
| 694 |  |  |  |  |  |  | =back | 
| 695 |  |  |  |  |  |  |  | 
| 696 |  |  |  |  |  |  | =cut | 
| 697 |  |  |  |  |  |  |  | 
| 698 |  |  |  |  |  |  | sub if_unprocessed_errors { | 
| 699 | 0 |  |  | 0 | 1 |  | my ($class) = @_; | 
| 700 |  |  |  |  |  |  |  | 
| 701 | 0 |  |  |  |  |  | my $n = scalar(@{$class->{'ERRORS_UNPROC'}}); | 
|  | 0 |  |  |  |  |  |  | 
| 702 |  |  |  |  |  |  |  | 
| 703 | 0 | 0 |  |  |  |  | if ($n == 0) { | 
| 704 | 0 |  |  |  |  |  | return; | 
| 705 |  |  |  |  |  |  | } | 
| 706 |  |  |  |  |  |  |  | 
| 707 | 0 |  |  |  |  |  | return $n; | 
| 708 |  |  |  |  |  |  | } | 
| 709 |  |  |  |  |  |  |  | 
| 710 |  |  |  |  |  |  | 1; | 
| 711 |  |  |  |  |  |  |  | 
| 712 |  |  |  |  |  |  | __END__ |