File Coverage

blib/lib/WebService/Vtiger.pm
Criterion Covered Total %
statement 15 113 13.2
branch 0 14 0.0
condition n/a
subroutine 5 17 29.4
pod 9 9 100.0
total 29 153 18.9


line stmt bran cond sub pod time code
1             package WebService::Vtiger;
2              
3 1     1   27374 use warnings;
  1         2  
  1         25  
4 1     1   5 use strict;
  1         2  
  1         27  
5              
6 1     1   1138 use LWP::UserAgent;
  1         102998  
  1         35  
7 1     1   1248 use JSON;
  1         19177  
  1         12  
8 1     1   214 use Digest::MD5;
  1         5  
  1         2249  
9              
10              
11             =head1 NAME
12              
13             Webservice::Vtiger - Interface to vtiger5.2 webservices
14              
15             =head1 VERSION
16              
17             Version 0.01
18              
19             =cut
20              
21             our $VERSION = '1.01';
22              
23             =head1 SYNOPSIS
24              
25             Class that handles the webservice interface to vtiger.
26              
27             The basic object in that transactions is $session that holds sessionName and userId values. This values will be used to perform request services
28              
29             use Webservice::Vtiger;
30              
31             my $vt = new Webservice::Vtiger();
32             my $usermane = 'admin';
33             my $pin = 'f956n34fc6';
34            
35             my $session = $vt->getSession($username, $pin);
36            
37             With a 'Session Id' string we can perform querys:
38              
39             my $contacts = $vt->query(
40             $session->{'sessionName'},
41             "select * from Contacts;"
42             );
43              
44             =head1 CRUD
45              
46             To change vtiger objects we need the userId holded by our session object.
47              
48             =head2 CREATE
49              
50             # create a new contact
51             my $ctcData = {
52             'assigned_user_id'=> $session->{'userId'},
53             'lastname' => 'Filipo'
54             };
55              
56             my $newContact = $vt->create(
57             $session->{'sessionName'},
58             'Contacts',
59             $ctcData
60             );
61              
62             =head2 RETRIEVE
63              
64             my $retrieved =$vt->retrieve($session->{'sessionName'}, $contactId);
65            
66             =head2 UPDATE
67              
68             $retrieved->{'lastname'} = "Filapo";
69             $vt->update($session->{'sessionName'},$retrieved)
70              
71             =head2 DELETE
72              
73             my $deleted =$vt->delete($session->{'sessionName'}, $contactId);
74              
75             =head1 SUBROUTINES/METHODS
76              
77             =head2 new
78              
79             A Webservice::Vtiger object can be instantiated by the new method.
80              
81             The module instance has blessed 4 attributes:
82              
83             =over 2
84              
85             =item * ua: the browser
86              
87             Instance of LWP::UserAgent
88              
89             =item * json: the json handler
90              
91             Instance of JSON
92              
93             =item * ctx: the MD5 handler
94              
95             Instance of Digest::MD5
96              
97             =item * url: the url of vtiger5.2 CRM
98              
99             =back
100              
101             =cut
102              
103             sub new {
104 0     0 1   my $class = shift;
105 0           my $url = shift;
106 0           my $self = {
107             'ua' => LWP::UserAgent->new, # browser
108             'json' => JSON->new->allow_nonref, # json handler
109             'ctx' => Digest::MD5->new, # MD5 handler
110             'url' => $url # vtiger service url
111             };
112 0           bless $self, $class;
113              
114 0           $self->{'ua'}->agent("synodos filos/$VERSION");
115 0           return $self;
116             }
117              
118             =head2 getSession
119              
120             Returns a session object.
121              
122             A session holds sessionName and userId values.
123              
124             This values must be used to identify the user in web services requests.
125              
126             my $sessionName = $session->{'sessionName'};
127             my $userId = $session->{'userId'};
128              
129             =cut
130              
131             sub getSession {
132 0     0 1   my $self = shift;
133 0           my $username = shift;
134 0           my $pin = shift;
135 0           my $params = '?operation=getchallenge&username=' . $username;
136 0           my $session;
137              
138             # The login process need a challenge hash and a access key
139              
140 0           my $req = HTTP::Request->new( GET => $self->{'url'} . $params );
141 0           my $res = $self->{'ua'}->request($req);
142              
143 0           my $challenge = {};
144 0 0         if ( $res->is_success ) {
145 0           $challenge = $self->{'json'}->decode( $res->content );
146              
147             # the md5 digested access key
148 0           $self->{'ctx'}->add( $challenge->{result}{token} . $pin );
149 0           my $ak = $self->{'ctx'}->hexdigest;
150 0           $session = $self->_login( $username, $ak );
151             }
152             else {
153 0           die "Network fault! server response: " . $res->status_line, "\n";
154             }
155 0           return $session;
156             }
157              
158             sub _login {
159 0     0     my $self = shift;
160 0           my $un = shift;
161 0           my $ak = shift;
162              
163             # we need a POST request
164 0           my $req = HTTP::Request->new( POST => $self->{'url'} );
165 0           $req->content_type('application/x-www-form-urlencoded');
166 0           $req->content( 'operation=login&username=' . $un . '&accessKey=' . $ak );
167              
168             # Pass the request to user agent and get response back
169 0           my $res = $self->{'ua'}->request($req);
170 0           my $jsonResponse = {};
171 0 0         if ( $res->is_success ) {
172 0           $jsonResponse = $self->{'json'}->decode( $res->content );
173 0 0         die( 'Login fault: ' . $jsonResponse->{error}{message} )
174             unless $jsonResponse->{'success'} eq 'true';
175 0           my $result = $jsonResponse->{result};
176              
177             #use Data::Dumper;
178             #print Dumper $result;
179 0           return $result;
180             }
181             else {
182 0           die("Connection error\n");
183             }
184             }
185              
186             =head2 describe
187              
188             Returns the vtiger module descripton.
189              
190             my $description = $vt->describe{$sessionName, $module};
191             my @fieldNames = @{$description->{'fields'}};
192              
193             The description consists of the following fields:
194              
195             =over 2
196              
197             =item * label - The label used for the name of the module.
198              
199             =item * name - The name of the module.
200              
201             =item * createable - A boolean value specifying whether the object can be created.
202              
203             =item * updateable - A boolean value specifying whether the object can be updated.
204              
205             =item * deleteable - A boolean value specifying whether the object can be deleted.
206              
207             =item * retrieveable - A boolean value specifying whether the object can be retrieved.
208              
209             =item * fields - An array containing the field names and their type information.
210              
211             =back
212              
213             Each element in the fields array describes a particular field in the object.
214              
215             =over 2
216              
217             =item * name - The name of the field, as used internally by vtiger.
218              
219             =item * label - The label used for displaying the field name.
220              
221             =item * mandatory - This is a boolean that specifies whether the field is mandatory, mandatory fields must be provided when creating a new object.
222              
223             =item * type - An map that describes the type information for the field.
224              
225             =item * default - The default value for the field.
226              
227             =item * nillable - A boolean that specifies whether the field can be set to null.
228              
229             =item * editable - A boolean that specifies whether the field can be modified.
230              
231             =back
232              
233             The type field is of particular importance as it describes what type of the field is. This is an map that will contain at the least an element called name which is the name of the type. The name could be one of the following.
234              
235             =over 2
236              
237             =item * string - A one line text field.
238              
239             =item * text - A multiline text field.
240              
241             =item * integer - A non decimal number field.
242              
243             =item * double - A field for for floating point numbers.
244              
245             =item * boolean - A boolean field, can have the values true or false.
246              
247             =item * time - A string of the format hh:mm, format is based on the user's settings time format.
248              
249             =item * date - A string representing a date, the type map will contain another element called format which is the format in which the value of this field is expected, its based on the user's settings date format.
250              
251             =item * datetime - A string representing the date and time, the format is base on the user's settings date format.
252              
253             =item * autogenerated - Thes are fields for which the values are generated automatically by vtiger, this is usually an object's id field.
254              
255             =item * reference - A field that shows a relation to another object, the type map will contain another element called refersTo which is an array containing the name of modules of which the field can point to.
256              
257             =item * picklist - A field that can a hold one of a list of values, the map will contain two elements, picklistValues which is a list of possible values, and defaultValue which is the default value for the picklist.
258              
259             =item * multipicklist - A picklist field where multiple values can be selected.
260              
261             =item * phone - A field for storing phone numbers
262              
263             =item * email - A field for storing email ids
264              
265             =item * url - A field for storing urls
266              
267             =item * skype - A field for storing skype ids or phone numbers.
268              
269             =item * password - A field for storing passwords.
270              
271             =item * owner - A field for defining the owner of the field. which could be a group or individual user.
272              
273             =back
274              
275             =cut
276              
277             sub describe {
278 0     0 1   my $self = shift;
279 0           my $sessionId = shift;
280 0           my $module = shift;
281 0           my $params =
282             '?sessionName='
283             . $sessionId
284             . '&elementType='
285             . $module
286             . '&operation=describe';
287 0           my $result = $self->_getVtiger($params);
288              
289             #use Data::Dumper;
290             #print Dumper $result;
291              
292 0           return $result;
293             }
294              
295             =head2 create
296              
297             =cut
298              
299             sub create {
300 0     0 1   my $self = shift;
301 0           my $sessionId = shift;
302 0           my $moduleName = shift;
303 0           my $data = shift;
304              
305 0           my $objectJson = $self->{'json'}->encode($data);
306 0           my $params = {
307             (
308             'sessionName' => $sessionId,
309             'operation' => 'create',
310             'element' => $objectJson,
311             'elementType' => $moduleName
312             )
313             };
314 0           my $result = $self->_postVtiger($params);
315 0           return $result;
316             }
317              
318             =head2 delete
319              
320             =cut
321              
322             sub delete {
323 0     0 1   my $self = shift;
324 0           my $sessionId = shift;
325 0           my $id = shift;
326              
327 0           my $params = {
328             (
329             'sessionName' => $sessionId,
330             'id' => $id,
331             'operation' => 'delete'
332             )
333             };
334 0           $self->_postVtiger($params);
335 0           return 'deleted';
336             }
337              
338             =head2 update
339              
340             =cut
341              
342             sub update {
343 0     0 1   my $self = shift;
344 0           my $sessionId = shift;
345 0           my $data = shift;
346              
347 0           my $objectJson = $self->{'json'}->encode($data);
348 0           my $params = {
349             (
350             'sessionName' => $sessionId,
351             'operation' => 'update',
352             'element' => $objectJson,
353             )
354             };
355 0           my $result = $self->_postVtiger($params);
356 0           return $result;
357             }
358              
359             =head2 query
360              
361             =cut
362              
363             sub query {
364 0     0 1   my $self = shift;
365 0           my $sessionId = shift;
366 0           my $query = shift;
367 0           my $params =
368             '?sessionName=' . $sessionId . '&operation=query&query=' . $query;
369 0           my $result = $self->_getVtiger($params);
370              
371             #use Data::Dumper;
372             #print Dumper $result->[0];
373              
374 0           return $result;
375             }
376              
377             =head2 retrieve
378              
379             =cut
380              
381             sub retrieve {
382 0     0 1   my $self = shift;
383 0           my $sessionId = shift;
384 0           my $id = shift;
385 0           my $params = '?sessionName=' . $sessionId . '&operation=retrieve&id=' . $id;
386 0           my $result = $self->_getVtiger($params);
387              
388             #use Data::Dumper;
389             #print Dumper $result;
390 0           return $result;
391             }
392              
393             =head2 listModules
394              
395             =cut
396              
397             sub listModules {
398 0     0 1   my $self = shift;
399 0           my $sessionId = shift;
400 0           my $params = '?sessionName=' . $sessionId . '&operation=listtypes';
401 0           my $result = $self->_getVtiger($params);
402 0           return $result;
403             }
404              
405             sub _getVtiger {
406 0     0     my $self = shift;
407 0           my $params = shift;
408              
409             #use Data::Dumper;
410             #print Dumper $params;
411              
412 0           my $req = HTTP::Request->new( GET => $self->{'url'} . $params );
413 0           my $res = $self->{'ua'}->request($req);
414              
415             #my $res = $self->{'ua'}->get( $self->{'url'}, $params );
416              
417 0           my $jsonResponse = {};
418 0 0         if ( $res->is_success ) {
419              
420 0           $jsonResponse = $self->{'json'}->decode( $res->content );
421 0 0         die( 'Service fault! ' . $jsonResponse->{'error'}{'message'} )
422             unless $jsonResponse->{'success'} eq 'true';
423 0           return $jsonResponse->{result};
424             }
425             else {
426 0           die("Connection error\n");
427             }
428             }
429              
430             sub _postVtiger {
431 0     0     my $self = shift;
432 0           my $params = shift;
433              
434             #use Data::Dumper;
435             #print Dumper $params;
436              
437 0           my $res = $self->{'ua'}->post( $self->{'url'}, $params );
438 0           my $jsonResponse = {};
439 0 0         if ( $res->is_success ) {
440 0           $jsonResponse = $self->{'json'}->decode( $res->content );
441              
442             #print ($jsonResponse->{error}{xdebug_message});
443 0 0         die( 'POST fault: '
444             . $jsonResponse->{error}{message} . "\n"
445             . $self->{'url'} )
446             unless $jsonResponse->{'success'} eq 'true';
447 0           return $jsonResponse->{result};
448             }
449             else {
450 0           die("Connection error (POST)\n$@\n");
451             }
452             }
453              
454             =head1 AUTHOR
455              
456             Monsenhor, C<< >>
457              
458             =head1 BUGS
459              
460             Please report any bugs or feature requests to C, or through
461             the web interface at L. I will be notified, and then you'll
462             automatically be notified of progress on your bug as I make changes.
463              
464              
465              
466              
467             =head1 SUPPORT
468              
469             You can find documentation for this module with the perldoc command.
470              
471             perldoc WebService::Vtiger
472              
473              
474             You can also look for information at:
475              
476             =over 4
477              
478             =item * RT: CPAN's request tracker
479              
480             L
481              
482             =item * AnnoCPAN: Annotated CPAN documentation
483              
484             L
485              
486             =item * CPAN Ratings
487              
488             L
489              
490             =item * Search CPAN
491              
492             L
493              
494             =back
495              
496              
497             =head1 ACKNOWLEDGEMENTS
498              
499              
500             =head1 LICENSE AND COPYRIGHT
501              
502             Copyright 2011 Monsenhor.
503              
504             This program is free software; you can redistribute it and/or modify it
505             under the terms of either: the GNU General Public License as published
506             by the Free Software Foundation; or the Artistic License.
507              
508             See http://dev.perl.org/licenses/ for more information.
509              
510              
511             =cut
512              
513             1; # End of WebService::Vtiger