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 |