Written by: Jonathan Maron.

The goal of the LiveDocx Zend Framework component phpLiveDocx is to make the interaction with the backend SOAP service LiveDocx as simple and as native to PHP as possible. phpLiveDocx embodies the KISS principle of the Zend Framework.

Technically, however, it is possible to instantiate and interact with the SOAP service directly from PHP. PHP 5 ships with the excellent SoapClient, which offers almost all the functionality that is required.

Checking for the SOAP extension

Although the SOAP extension is available on most PHP 5 installations, it is possible to disable it. To ensure you have the SOAP extension installed and enabled, take a look at the output of echo phpinfo();. If you see the following section, you are good to go.

PHP 5 Soap extension

If you do not see the above, you have two choices:

  1. Contact your system administrator or hosting company and ask them to install the
    PHP 5 SOAP extension.
  2. Download, install and deploy NuSOAP (SOAP client) to connect to the back end service.
    This article explains how.

The devil is in the detail

Using LiveDocx directly in PHP is not as simple as it may sound – otherwise there would not have been any reason to build the Zend Framework components for LiveDocx in the first place. The devil, as they say, is in the detail.

The data structures, which are sent to LiveDocx can be tricky to get right in PHP, as they appear unusual to a PHP developer. Review the following functions below for details:

1
2
function assocArrayToArrayOfArrayOfString($assoc) {}
function multiAssocArrayToArrayOfArrayOfString($multi) {}

Similarly, the data structures which are returned from LiveDocx can be tricky to understand when you are just starting out – in particular, if you are not familiar with SOAP’s complex data types. Moreover, depending upon whether one or more pieces of data are returned, their structure differs. Review the following structures below for details:

1
$result->{MethodName}Result->string

The way in which parameters must be assigned to the LiveDocx SOAP methods is again unusual to a PHP developer. For example, instead of calling a method the usual way:

1
$mailMerge->LogIn(USERNAME, PASSWORD);

using SOAP directly, you must pass the parameters as an associative array:

1
2
3
4
5
6
$soap->LogIn(
    array(
        'username' => USERNAME,
        'password' => PASSWORD
    )
);

Furthermore, the continuous base64 encoding and decoding of binary data can become very tedious.

Although phpLiveDocx has been designed from the ground up to be a thin layer, mimicking the API of the backend service, it does offer some functionality of its own. For example, phpLiveDocx bundles SOAP requests, thus speeding up communication with the backend service and allows PDF properties to be set from program code.

Basically, if you want to make your life easy, use the Zend Framework component; if you do not mind getting your hands dirty, you may like to try using LiveDocx natively.

Native SOAP samples

Before you start reviewing the code below, please download the following template files:

Copy them into the same directory as the executable file containing the following PHP 5 code. Secondly, specify the constants USERNAME and PASSWORD, which you received after signing up for an account.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
#!/usr/bin/php
<?php
 
// Turn up error reporting
error_reporting (E_ALL|E_STRICT);
 
// Turn off WSDL caching
ini_set ('soap.wsdl_cache_enabled', 0);
 
// Define credentials for LD
define ('USERNAME', 'yourUsername');
define ('PASSWORD', 'yourPassword');
 
// SOAP WSDL endpoint
define ('ENDPOINT', 'https://api.livedocx.com/1.2/mailmerge.asmx?WSDL');
 
// Define timezone
date_default_timezone_set('Europe/Berlin');
 
// -----------------------------------------------------------------------------
 
//
// SAMPLE #1 - License Agreement
//
 
print('Starting sample #1 (license-agreement)...');
 
// Instantiate SOAP object and log into LiveDocx
 
$soap = new SoapClient(ENDPOINT);
 
$soap->LogIn(
    array(
        'username' => USERNAME,
        'password' => PASSWORD
    )
);
 
// Upload template
 
$data = file_get_contents('./license-agreement-template.docx');
 
$soap->SetLocalTemplate(
    array(
        'template' => base64_encode($data),
        'format'   => 'docx'
    )
);
 
// Assign data to template
 
$fieldValues = array (
    'software' => 'Magic Graphical Compression Suite v2.5',
    'licensee' => 'Henry Döner-Meyer',
    'company'  => 'Megasoft Co-Operation',
    'date'     => date('F d, Y'),
    'time'     => date('H:i:s'),
    'city'     => 'Berlin',
    'country'  => 'Germany'
);
 
$soap->SetFieldValues(
    array (
        'fieldValues' => assocArrayToArrayOfArrayOfString($fieldValues)
    )
);
 
// Build the document
 
$soap->CreateDocument();
 
// Get document as PDF
 
$result = $soap->RetrieveDocument(
    array(
        'format' => 'pdf'
    )
);
 
$data = $result->RetrieveDocumentResult;
 
file_put_contents('./license-agreement-document.pdf', base64_decode($data));
 
// Get document as bitmaps (one per page)
 
$result = $soap->GetAllBitmaps(
    array(
        'zoomFactor' => 100,
        'format'     => 'png'
    )
);
 
$data = array();
 
if (isset($result->GetAllBitmapsResult->string)) {
    $pageCounter = 1;
    if (is_array($result->GetAllBitmapsResult->string)) {
        foreach ($result->GetAllBitmapsResult->string as $string) {
            $data[$pageCounter] = base64_decode($string);
            $pageCounter++;
        }
    } else {
       $data[$pageCounter] = base64_decode($result->GetAllBitmapsResult->string);
    }
}
 
foreach ($data as $pageCounter => $pageData) {
    $pageFilename = sprintf('./license-agreement-document-page-%s.png', $pageCounter);
    file_put_contents($pageFilename, $pageData);    
}
 
// Get document as Windows metafiles (one per page)
 
$result = $soap->GetAllMetafiles();
 
$data = array();
 
if (isset($result->GetAllMetafilesResult->string)) {
    $pageCounter = 1;
    if (is_array($result->GetAllMetafilesResult->string)) {
        foreach ($result->GetAllMetafilesResult->string as $string) {
            $data[$pageCounter] = base64_decode($string);
            $pageCounter++;
        }
    } else {
       $data[$pageCounter] = base64_decode($result->GetAllMetafilesResult->string);
    }
}
 
foreach ($data as $pageCounter => $pageData) {
    $pageFilename = sprintf('./license-agreement-document-page-%s.wmf', $pageCounter);
    file_put_contents($pageFilename, $pageData);    
}
 
// Log out (closes connection to backend server)
 
$soap->LogOut();
 
unset($soap);
 
print('DONE.' . PHP_EOL);
 
// -----------------------------------------------------------------------------
 
//
// SAMPLE #2 - Telephone Bill
//
 
print('Starting sample #2 (telephone-bill)...');
 
// Instantiate SOAP object and log into LiveDocx
 
$soap = new SoapClient(ENDPOINT);
 
$soap->LogIn(
    array(
        'username' => USERNAME,
        'password' => PASSWORD
    )
);
 
// Upload template
 
$data = file_get_contents('./telephone-bill-template.doc');
 
// Assign field values data to template
 
$soap->SetLocalTemplate(
    array(
        'template' => base64_encode($data),
        'format'   => 'doc'
    )
);
 
$fieldValues = array (
    'customer_number' => sprintf("#%'10s",  rand(0,1000000000)),
    'invoice_number'  => sprintf("#%'10s",  rand(0,1000000000)),
    'account_number'  => sprintf("#%'10s",  rand(0,1000000000)),
    'phone'           => '+49 421 335 9000',
    'date'            => date('F d, Y'),
    'name'            => 'James Henry Brown',
    'service_phone'   => '+49 421 335 910',
    'service_fax'     => '+49 421 335 9180',
    'month'           => date('F Y'),
    'monthly_fee'     =>  '€ 15.00',
    'total_net'       => '€ 100.00',
    'tax'             =>      '19%',
    'tax_value'       =>  '€ 15.00',
    'total'           => '€ 130.00'
);
 
$soap->SetFieldValues(
    array (
        'fieldValues' => assocArrayToArrayOfArrayOfString($fieldValues)
    )
);
 
// Assign block field values data to template
 
$blockFieldValues = array (
    array ('connection_number' => '+49 421 335 912', 'connection_duration' => '00:00:07', 'fee' => '€ 0.03'),
    array ('connection_number' => '+49 421 335 913', 'connection_duration' => '00:00:07', 'fee' => '€ 0.03'),
    array ('connection_number' => '+49 421 335 914', 'connection_duration' => '00:00:07', 'fee' => '€ 0.03'),
    array ('connection_number' => '+49 421 335 916', 'connection_duration' => '00:00:07', 'fee' => '€ 0.03')
);
 
$soap->SetBlockFieldValues(
    array (
        'blockName'        => 'connection',
        'blockFieldValues' => multiAssocArrayToArrayOfArrayOfString($blockFieldValues)
    )
);
 
// Build the document
 
$soap->CreateDocument();
 
// Get document as PDF
 
$result = $soap->RetrieveDocument(
    array(
        'format' => 'pdf'
    )
);
 
$data = $result->RetrieveDocumentResult;
 
file_put_contents('./telephone-bill-document.pdf', base64_decode($data));
 
// Log out (closes connection to backend server)
 
$soap->LogOut();
 
unset($soap);
 
print('DONE.' . PHP_EOL);
 
// -----------------------------------------------------------------------------
 
//
// SAMPLE #3 - Supported Formats
//
 
print('Starting sample #3 (supported-formats)...' . PHP_EOL);
 
// Instantiate SOAP object and log into LiveDocx
 
$soap = new SoapClient(ENDPOINT);
 
$soap->LogIn(
    array(
        'username' => USERNAME,
        'password' => PASSWORD
    )
);
 
// Get an object containing an array of supported template formats
 
$result = $soap->GetTemplateFormats();
 
print(PHP_EOL . 'Template format (input):' . PHP_EOL);
 
foreach ($result->GetTemplateFormatsResult->string as $format) {
    printf('- %s%s', $format, PHP_EOL);
}
 
// Get an object containing an array of supported document formats
 
print(PHP_EOL . 'Document format (output):' . PHP_EOL);
 
$result = $soap->GetDocumentFormats();
 
foreach ($result->GetDocumentFormatsResult->string as $format) {
    printf('- %s%s', $format, PHP_EOL);
}
 
// Get an object containing an array of supported image formats
 
print(PHP_EOL . 'Image format (output):' . PHP_EOL);
 
$result = $soap->GetImageFormats();
 
foreach ($result->GetImageFormatsResult->string as $format) {
    printf('- %s%s', $format, PHP_EOL);
}
 
print(PHP_EOL . 'DONE.' . PHP_EOL);
 
// Log out (closes connection to backend server)
 
$soap->LogOut();
 
unset($soap);
 
// -----------------------------------------------------------------------------
 
//
// SAMPLE #4 - Supported Formats
//
 
print('Starting sample #4 (supported-fonts)...' . PHP_EOL);
 
// Instantiate SOAP object and log into LiveDocx
 
$soap = new SoapClient(ENDPOINT);
 
$soap->LogIn(
    array(
        'username' => USERNAME,
        'password' => PASSWORD
    )
);
 
// Get an object containing an array of supported fonts
 
$result = $soap->GetFontNames();
 
foreach ($result->GetFontNamesResult->string as $format) {
    printf('- %s%s', $format, PHP_EOL);
}
 
print(PHP_EOL . 'DONE.' . PHP_EOL);
 
// Log out (closes connection to backend server)
 
$soap->LogOut();
 
unset($soap);
 
// -----------------------------------------------------------------------------
 
/**
 * Convert a PHP assoc array to a SOAP array of array of string
 *
 * @param array $assoc
 * @return array
 */
function assocArrayToArrayOfArrayOfString ($assoc)
{
    $arrayKeys   = array_keys($assoc);
    $arrayValues = array_values($assoc);
 
    return array ($arrayKeys, $arrayValues);
}
 
/**
 * Convert a PHP multi-depth assoc array to a SOAP array of array of array of string
 *
 * @param array $multi
 * @return array
 */
function multiAssocArrayToArrayOfArrayOfString ($multi)
{
    $arrayKeys   = array_keys($multi[0]);
    $arrayValues = array();
 
    foreach ($multi as $v) {
        $arrayValues[] = array_values($v);
    }
 
    $_arrayKeys = array();
    $_arrayKeys[0] = $arrayKeys;
 
    return array_merge($_arrayKeys, $arrayValues);
}

API documentation

You can read full API documentation here and the current WSDL here.

Need help?

Please post all requests for support into the phpLiveDocx support forum.