File Coverage

blib/lib/Polycom/Contact.pm
Criterion Covered Total %
statement 23 69 33.3
branch 1 28 3.5
condition 8 54 14.8
subroutine 7 11 63.6
pod 4 4 100.0
total 43 166 25.9


line stmt bran cond sub pod time code
1             package Polycom::Contact;
2 3     3   86707 use strict;
  3         8  
  3         114  
3 3     3   18 use warnings;
  3         5  
  3         91  
4 3     3   16 use base qw(Class::Accessor);
  3         10  
  3         5624  
5            
6             our $VERSION = 0.05;
7            
8             use overload (
9 0     0   0 '==' => sub { !$_[0]->diff($_[1]) },
10 0     0   0 '!=' => sub { scalar $_[0]->diff($_[1]) },
11             '""' => sub {
12 3     3   34 my $name = join ' ', grep {defined} ($_[0]->{first_name}, $_[0]->{last_name});
  6         21  
13 3         9 return join ' at ', grep {$_} ($name, $_[0]->{contact});
  6         32  
14             },
15 3     3   13677 );
  3         3642  
  3         39  
16            
17             Polycom::Contact->mk_accessors(
18             qw(first_name last_name contact speed_index label ring_type divert
19             auto_reject auto_divert buddy_watching buddy_block in_storage)
20             );
21            
22             ###################
23             # Constructors
24             ###################
25             sub new
26             {
27 19     19 1 1727 my ($class, %args) = @_;
28            
29 19   50     488 my $self = {
      50        
      50        
      50        
      50        
      100        
30             first_name => $args{first_name},
31             last_name => $args{last_name},
32             contact => $args{contact},
33             speed_index => $args{speed_index},
34             label => $args{label},
35             ring_type => $args{ring_type},
36             divert => $args{divert} || 0,
37             auto_reject => $args{auto_reject} || 0,
38             auto_divert => $args{auto_divert} || 0,
39             buddy_watching => $args{buddy_watching} || 0,
40             buddy_block => $args{buddy_block} || 0,
41             in_storage => $args{in_storage} || 0,
42             };
43            
44 19 50 33     108 if (!defined $self->{contact} || $self->{contact} eq '')
45             {
46 0         0 warn "No 'contact' attribute specified";
47             }
48            
49 19         184 return bless $self, $class;
50             }
51            
52             ###################
53             # Public Methods
54             ###################
55             sub is_valid
56             {
57 0     0 1 0 my ($self, $reason) = @_;
58            
59 0 0 0     0 if (defined $self->first_name && length $self->first_name > 40)
60             {
61 0         0 $reason = 'first_name must be <= 40 bytes long';
62 0         0 return;
63             }
64            
65 0 0 0     0 if (defined $self->last_name && length $self->last_name > 40)
66             {
67 0         0 $reason = 'last_name must be <= 40 bytes long';
68 0         0 return;
69             }
70            
71 0 0 0     0 if (!defined $self->contact || $self->contact eq '')
72             {
73 0         0 $reason = 'contact is a required field';
74 0         0 return;
75             }
76            
77 0 0 0     0 if ( defined $self->speed_index
      0        
78             && ($self->speed_index !~ /^\d*$/
79             || $self->speed_index < 1
80             || $self->speed_index > 9999))
81             {
82 0         0 $reason = 'speed_index must be a number between 1 and 9999';
83 0         0 return;
84             }
85            
86 0 0 0     0 if ( defined $self->ring_type
      0        
87             && ($self->ring_type !~ /^\d*$/
88             || $self->ring_type < 1
89             || $self->ring_type > 21))
90             {
91 0         0 $reason = 'ring_type must be a number between 1 and 21';
92 0         0 return;
93             }
94            
95 0 0 0     0 if (defined $self->auto_divert && $self->auto_divert !~ /^[01]?$/)
96             {
97 0         0 $reason = 'auto_divert must be either "", 0, or 1';
98 0         0 return;
99             }
100            
101 0 0 0     0 if (defined $self->auto_reject && $self->auto_reject !~ /^[01]?$/)
102             {
103 0         0 $reason = 'auto_reject must be either "", 0, or 1';
104 0         0 return;
105             }
106            
107 0 0 0     0 if (defined $self->buddy_watching && $self->buddy_watching !~ /^[01]?$/)
108             {
109 0         0 $reason = 'buddy_watching must be either "", 0, or 1';
110 0         0 return;
111             }
112            
113 0 0 0     0 if (defined $self->buddy_block && $self->buddy_block !~ /^[01]?$/)
114             {
115 0         0 $reason = 'buddy_block must be either "", 0, or 1';
116 0         0 return;
117             }
118            
119 0         0 return 1;
120             }
121            
122             sub delete
123             {
124 3     3 1 7215 my ($self) = @_;
125 3         9 $self->{in_storage} = 0;
126 3         10 return;
127             }
128            
129             sub diff
130             {
131 0     0 1   my ($self, $other) = @_;
132            
133             # Map each contact attribute to a "nice" name (e.g. first_name => "First Name")
134 0           my %LABELS = (
135             first_name => 'First Name',
136             last_name => 'Last Name',
137             contact => 'Number',
138             speed_index => 'Speed Index',
139             label => 'Label',
140             ring_type => 'Ring Type',
141             divert => 'Divert',
142             auto_reject => 'Auto Reject',
143             auto_divert => 'Auto Divert',
144             buddy_watching => 'Buddy Watch',
145             buddy_block => 'Buddy Block',
146             );
147            
148 0           my @nonMatchingFields;
149 0           while (my ($attr, $label) = each %LABELS)
150             {
151 0 0         my $mine = defined $self->{$attr} ? $self->{$attr} : 0;
152 0 0         my $theirs = defined $other->{$attr} ? $other->{$attr} : 0;
153            
154             # Normalize Boolean fields
155 0 0 0       if ( $attr eq 'auto_reject'
      0        
156             || $attr eq 'auto_divert'
157             || $attr eq 'buddy_watching')
158             {
159 0           $mine =~ s/Enabled/1/i;
160 0           $theirs =~ s/Enabled/1/i;
161 0           $mine =~ s/Disabled//i;
162 0           $theirs =~ s/Disabled//i;
163             }
164            
165 0 0         if ($mine ne $theirs)
166             {
167 0           push @nonMatchingFields, $attr;
168             }
169             }
170            
171 0           return @nonMatchingFields;
172             }
173            
174             =head1 NAME
175            
176             Polycom::Contact - Contact in a Polycom VoIP phone's local contact directory.
177            
178             =head1 SYNOPSIS
179            
180             use Polycom::Contact;
181            
182             # Create a new contact
183             my $contact = Polycom::Contact->new(
184             first_name => 'Bob',
185             last_name => 'Smith',
186             contact => '1234',
187             );
188            
189             # The contact can be interpolated in strings
190             # Prints: "The contact is: Bob Smith at 1234"
191             print "The contact is: $contact\n";
192            
193             # The contact can also be compared with other contacts
194             my $otherContact = Polycom::Contact->new(first_name => 'Jimmy', contact => '5678');
195             if ($otherContact != $contact)
196             {
197             print "$otherContact is not the same as $contact\n";
198             }
199            
200             # Or, of course, you can simply query the contact's fields
201             my $first_name = $contact->first_name;
202             my $last_name = $contact->last_name;
203            
204             =head1 DESCRIPTION
205            
206             The C class represents a contact in a Polycom SoundPoint IP, SoundStation IP, or VVX phone's local contact directory. This class is intended to be used with C, which parses entire contact directory files, extracting the contacts, and enabling you to read or modify them.
207            
208             =head1 CONSTRUCTOR
209            
210             =head2 new ( %fields )
211            
212             use Polycom::Contact;
213             my $contact = Polycom::Contact->new(first_name => 'Bob', contact => 1234);
214            
215             Returns a newly created C object.
216            
217             In all, each C object can have the following fields:
218            
219             first_name - first name
220             last_name - last name
221             contact - phone number or URL (required)
222             speed_index - speed dial index (1 - 9999)
223             label - label to show on speed dial keys
224             ring_type - distinctive incoming ring tone (1 - 22)
225             divert - phone number or URL to divert incoming calls to
226             auto_reject - automatically reject calls from this contact (0 = no, 1 = yes)
227             auto_divert - automatically divert calls from this contact (0 = no, 1 = yes)
228             buddy_watching - include in the list of watched phones (0 = no, 1 = yes)
229             buddy_block - block from watching this phone (0 = no, 1 = yes)
230            
231             Of those fields, the C field is the only required field; without a unique C field, the phone will not load the contact.
232            
233             =head1 ACCESSORS
234            
235             =head2 first_name
236            
237             my $fn = $contact->first_name;
238             $contact->first_name('Bob'); # Set the first_name to "Bob"
239            
240             =head2 last_name
241            
242             my $ln = $contact->last_name;
243             $contact->last_name('Smith'); # Set the last_name to "Smith"
244            
245             =head2 contact
246            
247             The phone number, extension, or URL of the contact. This field must be present (i.e. not blank) and must be unique.
248            
249             my $num = $contact->contact;
250             $contact->contact('1234'); # Set the contact number to 1234
251            
252             =head2 speed_index
253            
254             The speed dial index for the contact (1 - 9999).
255            
256             my $sd = $contact->speed_index;
257             $contact->speed_index(5); # Set the speed index to 5
258            
259             Contacts that have a speed dial index specified are listed in the phone's speed dial menu and are mapped to unused line keys for quick access.
260            
261             =head2 label
262            
263             The label to show on speed dial keys (e.g. "Manager").
264            
265             my $lb = $contact->label;
266             $contact->label('Sales'); # Set the label to "Sales"
267            
268             =head2 ring_type
269            
270             The distinctive incoming ring tone for this contact (1 - 22).
271            
272             my $rt = $contact->ring_type;
273             $contact->ring_type(2); # Set the ring type to 2
274            
275             The ring type number must correspond to a ring type listed in the I > I > I menu on the phone. When an incoming call is received from the contact, the specified ring tone will play instead of the default ring tone.
276            
277             =head2 divert
278            
279             The phone number or URL to divert incoming calls to.
280            
281             my $divert = $contact->divert;
282             $contact->divert(2345); # Set the divert phone number to 2345
283            
284             =head2 auto_reject
285            
286             Specifies whether to automatically reject calls from this contact (0 = no, 1 = yes).
287            
288             print "Calls from $contact will be automatically rejected" if ($contact->auto_reject);
289             $contact->auto_reject(1); # Enable auto reject
290            
291             =head2 auto_divert
292            
293             Specifies whether to automatically divert calls from this contact (0 = no, 1 = yes).
294            
295             print "Calls from $contact will be automatically diverted" if ($contact->auto_divert);
296             $contact->auto_divert(1); # Enable auto divert
297            
298             =head2 buddy_watching
299            
300             Specifies whether to include this contact in the list of watched phones (0 = no, 1 = yes).
301            
302             print "$contact is in the watched list" if ($contact->buddy_watching);
303             $contact->buddy_watching(1); # Add this contact to the buddy list
304            
305             =head2 buddy_block
306            
307             Specifies whether to block this contact from watching this phone (0 = no, 1 = yes).
308            
309             print "$contact is blocked from watching" if ($contact->buddy_block);
310             $contact->buddy_block(1); # Prevent this contact from watching this phone
311            
312             =head1 METHODS
313            
314             =head2 is_valid
315            
316             if (!$contact->is_valid)
317             {
318             print "$contact is invalid.\n";
319             }
320            
321             Returns I if the contact is invalid (i.e. it has no C value specified), or 1 otherwise.
322            
323             =head2 delete
324            
325             my @contacts = $dir->search({first_name => 'Bob'});
326             $contacts[0]->delete;
327            
328             Removes the contact from the directory it belongs to (see C).
329             If the C object was created from scratch, rather than from an existing
330             contact directory object, then calling C has no effect.
331            
332             =head2 diff ( $contact2 )
333            
334             my @differences = $contact1->diff($contact2);
335            
336             Returns an array of contact field names that do not match (e.g. "First Name", "Speed Dial").
337            
338             =head1 SEE ALSO
339            
340             C - A closely related module that parses the XML-based local contact directory file used by Polycom SoundPoint IP, SoundStation IP, and VVX VoIP phones, and can be used to read, modify, or create contacts in the file.
341            
342             =head1 AUTHOR
343            
344             Zachary Blair, Ezblair@cpan.orgE
345            
346             =head1 COPYRIGHT AND LICENSE
347            
348             Copyright (C) 2010 by Polycom Canada
349            
350             This library is free software; you can redistribute it and/or modify
351             it under the same terms as Perl itself, either Perl version 5.8.8 or,
352             at your option, any later version of Perl 5 you may have available.
353            
354             =cut
355            
356             'Together. Great things happen.';