Completed
Push — master ( 3fc782...8ee3b7 )
by Jonathan
03:44
created

ReportingCloud   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 505
Duplicated Lines 16.63 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 100%

Importance

Changes 14
Bugs 0 Features 0
Metric Value
wmc 50
lcom 1
cbo 7
dl 84
loc 505
rs 8.6206
c 14
b 0
f 0
ccs 213
cts 213
cp 1

14 Methods

Rating   Name   Duplication   Size   Complexity  
A getTemplateInfo() 0 20 3
B getTemplateThumbnails() 3 26 3
A getTemplateCount() 0 4 1
A getTemplatePageCount() 10 10 1
A templateExists() 10 10 1
A getTemplateList() 20 20 4
A getAccountSettings() 18 18 4
A downloadTemplate() 0 18 2
A get() 0 16 3
B uploadTemplate() 0 30 3
B convertDocument() 0 30 3
C mergeDocument() 13 63 11
B findAndReplaceDocument() 10 55 8
A deleteTemplate() 0 22 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ReportingCloud often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ReportingCloud, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * ReportingCloud PHP Wrapper
5
 *
6
 * PHP wrapper for ReportingCloud Web API. Authored and supported by Text Control GmbH.
7
 *
8
 * @link      http://www.reporting.cloud to learn more about ReportingCloud
9
 * @link      https://github.com/TextControl/txtextcontrol-reportingcloud-php for the canonical source repository
10
 * @license   https://raw.githubusercontent.com/TextControl/txtextcontrol-reportingcloud-php/master/LICENSE.md
11
 * @copyright © 2016 Text Control GmbH
12
 */
13
namespace TxTextControl\ReportingCloud;
14
15
use GuzzleHttp\Psr7\Response;
16
use GuzzleHttp\RequestOptions;
17
use TxTextControl\ReportingCloud\Exception\InvalidArgumentException;
18
use TxTextControl\ReportingCloud\Filter\StaticFilter;
19
use TxTextControl\ReportingCloud\PropertyMap\AccountSettings as AccountSettingsPropertyMap;
20
use TxTextControl\ReportingCloud\PropertyMap\TemplateInfo as TemplateInfoPropertyMap;
21
use TxTextControl\ReportingCloud\PropertyMap\TemplateList as TemplateListPropertyMap;
22
use TxTextControl\ReportingCloud\Validator\StaticValidator;
23
24
/**
25
 * ReportingCloud
26
 *
27
 * @package TxTextControl\ReportingCloud
28
 * @author  Jonathan Maron (@JonathanMaron)
29
 */
30
class ReportingCloud extends AbstractReportingCloud
31
{
32
33
    /**
34
     * GET methods
35
     * =================================================================================================================
36
     */
37
38
    /**
39
     * Return an array of merge blocks and merge fields in a template file in template storage.
40
     *
41
     * @param string  $templateName Template name
42
     *
43
     * @throws InvalidArgumentException
44
     *
45
     * @return array|null
46
     */
47 1
    public function getTemplateInfo($templateName)
48
    {
49 1
        $ret = null;
50
51 1
        $propertyMap = new TemplateInfoPropertyMap();
52
53 1
        StaticValidator::execute($templateName, 'TemplateName');
54
55
        $query = [
56 1
            'templateName' => $templateName,
57 1
        ];
58
59 1
        $records = $this->get('/templates/info', $query);
60
61 1
        if (is_array($records) && count($records) > 0) {
62 1
            $ret = $this->buildPropertyMapArray($records, $propertyMap);
63 1
        }
64
65 1
        return $ret;
66
    }
67
68
    /**
69
     * Return an array of binary data.
70
     * Each record in the array is the binary data of a thumbnail image
71
     *
72
     * @param string  $templateName Template name
73
     * @param integer $zoomFactor   Zoom factor
74
     * @param integer $fromPage     From page
75
     * @param integer $toPage       To page
76
     * @param string  $imageFormat  Image format
77
     *
78
     * @throws InvalidArgumentException
79
     *
80
     * @return array|null
81
     */
82 6
    public function getTemplateThumbnails($templateName, $zoomFactor, $fromPage, $toPage, $imageFormat)
83
    {
84 6
        $ret = null;
85
86 6
        StaticValidator::execute($templateName, 'TemplateName');
87 5
        StaticValidator::execute($zoomFactor  , 'ZoomFactor');
88 4
        StaticValidator::execute($fromPage    , 'Page');
89 3
        StaticValidator::execute($toPage      , 'Page');
90 2
        StaticValidator::execute($imageFormat , 'ImageFormat');
91
92
        $query = [
93 1
            'templateName' => $templateName,
94 1
            'zoomFactor'   => $zoomFactor,
95 1
            'fromPage'     => $fromPage,
96 1
            'toPage'       => $toPage,
97 1
            'imageFormat'  => $imageFormat,
98 1
        ];
99
100 1
        $records = $this->get('/templates/thumbnails', $query);
101
102 1 View Code Duplication
        if (is_array($records) && count($records) > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
103 1
            $ret = array_map('base64_decode', $records);
104 1
        }
105
106 1
        return $ret;
107
    }
108
109
    /**
110
     * Return the number of templates in template storage
111
     *
112
     * @return integer
113
     */
114 1
    public function getTemplateCount()
115
    {
116 1
        return (integer) $this->get('/templates/count');
117
    }
118
119
    /**
120
     * Return an array properties for the templates in template storage
121
     *
122
     * @return array|null
123
     */
124 1 View Code Duplication
    public function getTemplateList()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
125
    {
126 1
        $ret = null;
127
128 1
        $propertyMap = new TemplateListPropertyMap();
129
130 1
        $records = $this->get('/templates/list');
131
132 1
        if (is_array($records) && count($records) > 0) {
133 1
            $ret = $this->buildPropertyMapArray($records, $propertyMap);
134 1
            array_walk($ret, function (&$record) {
135 1
                $key = 'modified';
136 1
                if (isset($record[$key])) {
137 1
                    $record[$key] = StaticFilter::execute($record[$key], 'DateTimeToTimestamp');
138 1
                }
139 1
            });
140 1
        }
141
142 1
        return $ret;
143
    }
144
145
    /**
146
     * Return the number of pages in a template in template storage
147
     *
148
     * @param string $templateName Template name
149
     *
150
     * @throws InvalidArgumentException
151
     *
152
     * @return integer
153
     */
154 2 View Code Duplication
    public function getTemplatePageCount($templateName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
155
    {
156 2
        StaticValidator::execute($templateName, 'TemplateName');
157
158
        $query = [
159 1
            'templateName' => $templateName,
160 1
        ];
161
162 1
        return (integer) $this->get('/templates/pagecount', $query);
163
    }
164
165
    /**
166
     * Return true, if the template exists in template storage
167
     *
168
     * @param string $templateName Template name
169
     *
170
     * @throws InvalidArgumentException
171
     *
172
     * @return bool
173
     */
174 2 View Code Duplication
    public function templateExists($templateName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
175
    {
176 2
        StaticValidator::execute($templateName, 'TemplateName');
177
178
        $query = [
179 1
            'templateName' => $templateName,
180 1
        ];
181
182 1
        return (boolean) $this->get('/templates/exists', $query);
183
    }
184
185
    /**
186
     * Return an array properties for the ReportingCloud account
187
     *
188
     * @return array|null
189
     */
190 3 View Code Duplication
    public function getAccountSettings()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
191
    {
192 3
        $ret = null;
193
194 3
        $propertyMap = new AccountSettingsPropertyMap();
195
196 3
        $records = $this->get('/account/settings');
197
198 3
        if (is_array($records) && count($records) > 0) {
199 3
            $ret = $this->buildPropertyMapArray($records, $propertyMap);
200 3
            $key = 'valid_until';
201 3
            if ($ret[$key]) {
202 3
                $ret[$key] = StaticFilter::execute($ret[$key], 'DateTimeToTimestamp');
203 3
            }
204 3
        }
205
206 3
        return $ret;
207
    }
208
209
    /**
210
     * Download the binary data of a template from template storage
211
     *
212
     * @param string $templateName Template name
213
     *
214
     * @throws InvalidArgumentException
215
     *
216
     * @return null|resource
217
     */
218 2
    public function downloadTemplate($templateName)
219
    {
220 2
        $ret = null;
221
222 2
        StaticValidator::execute($templateName, 'TemplateName');
223
224
        $query = [
225 1
            'templateName' => $templateName,
226 1
        ];
227
228 1
        $data = $this->get('/templates/download', $query);
229
230 1
        if (null !== $data) {
231 1
            $ret = base64_decode($data);
232 1
        }
233
234 1
        return $ret;
235
    }
236
237
    /**
238
     * Execute a GET request via REST client
239
     *
240
     * @param string $uri   URI
241
     * @param array  $query Query
242
     *
243
     * @return mixed|null
244
     */
245 10
    protected function get($uri, $query = [])
246
    {
247 10
        $ret = null;
248
249
        $options = [
250 10
            RequestOptions::QUERY => $query,
251 10
        ];
252
253 10
        $response = $this->request('GET', $this->uri($uri), $options);
254
255 10
        if ($response instanceof Response && 200 === $response->getStatusCode()) {
256 10
            $ret  = json_decode($response->getBody(), true);
257 10
        }
258
259 10
        return $ret;
260
    }
261
262
263
    /**
264
     * POST methods
265
     * =================================================================================================================
266
     */
267
268
    /**
269
     * Upload a template to template storage
270
     *
271
     * @param string $templateFilename Template name
272
     *
273
     * @throws InvalidArgumentException
274
     *
275
     * @return bool
276
     */
277 13
    public function uploadTemplate($templateFilename)
278
    {
279 13
        $ret = false;
280
281 13
        StaticValidator::execute($templateFilename, 'TemplateExtension');
282 10
        StaticValidator::execute($templateFilename, 'FileExists');
283
284 9
        $templateFilename = realpath($templateFilename);
285 9
        $templateName     = basename($templateFilename);
286
287
        $query = [
288 9
            'templateName' => $templateName,
289 9
        ];
290
291 9
        $json = file_get_contents($templateFilename);
292 9
        $json = base64_encode($json);
293
294
        $options = [
295 9
            RequestOptions::QUERY => $query,
296 9
            RequestOptions::JSON  => $json,
297 9
        ];
298
299 9
        $response = $this->request('POST', $this->uri('/templates/upload'), $options);
300
301 9
        if ($response instanceof Response && 201 === $response->getStatusCode()) {
302 9
            $ret = true;
303 9
        }
304
305 9
        return $ret;
306
    }
307
308
    /**
309
     * Convert a document on the local file system to a different format
310
     *
311
     * @param string $documentFilename Document filename
312
     * @param string $returnFormat     Return format
313
     *
314
     * @throws InvalidArgumentException
315
     *
316
     * @return null|resource
317
     */
318 6
    public function convertDocument($documentFilename, $returnFormat)
319
    {
320 6
        $ret = null;
321
322 6
        StaticValidator::execute($documentFilename, 'DocumentExtension');
323 3
        StaticValidator::execute($documentFilename, 'FileExists');
324 2
        StaticValidator::execute($returnFormat    , 'ReturnFormat');
325
326
        $query = [
327 1
            'returnFormat' => $returnFormat,
328 1
        ];
329
330 1
        $documentFilename = realpath($documentFilename);
331
332 1
        $json = file_get_contents($documentFilename);
333 1
        $json = base64_encode($json);
334
335
        $options = [
336 1
            RequestOptions::QUERY => $query,
337 1
            RequestOptions::JSON  => $json,
338 1
        ];
339
340 1
        $response = $this->request('POST', $this->uri('/document/convert'), $options);
341
342 1
        if ($response instanceof Response && 200 === $response->getStatusCode()) {
343 1
            $ret  = base64_decode($response->getBody());
344 1
        }
345
346 1
        return $ret;
347
    }
348
349
    /**
350
     * Merge data into a template and return an array of binary data.
351
     * Each record in the array is the binary data of one document
352
     *
353
     * @param array   $mergeData        Array of merge data
354
     * @param string  $returnFormat     Return format
355
     * @param string  $templateName     Template name
356
     * @param string  $templateFilename Template filename on local file system
357
     * @param boolean $append           Append flag
358
     * @param array   $mergeSettings    Array of merge settings
359
     *
360
     * @throws InvalidArgumentException
361
     *
362
     * @return null|string
363
     */
364 15
    public function mergeDocument($mergeData, $returnFormat, $templateName = null, $templateFilename = null,
365
                                    $append = null, $mergeSettings = [])
366
    {
367 15
        $ret = null;
368
369 15
        StaticValidator::execute($mergeData   , 'TypeArray');
370 15
        StaticValidator::execute($returnFormat, 'ReturnFormat');
371
372 14
        if (null !== $templateName) {
373 2
            StaticValidator::execute($templateName, 'TemplateName');
374 1
        }
375
376 13 View Code Duplication
        if (null !== $templateFilename) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
377 12
            StaticValidator::execute($templateFilename, 'TemplateExtension');
378 9
            StaticValidator::execute($templateFilename, 'FileExists');
379 8
            $templateFilename = realpath($templateFilename);
380 8
        }
381
382 9
        if (null !== $append) {
383 6
            $append = StaticFilter::execute($append, 'BooleanToString');
384 5
        }
385
386 8
        StaticValidator::execute($mergeSettings, 'TypeArray');
387
388
        $query = [
389 7
            'returnFormat' => $returnFormat,
390 7
            'append'       => $append,
391 7
        ];
392
393 7
        if (null !== $templateName) {
394 1
            $query['templateName'] = $templateName;
395 1
        }
396
397
        $json = [
398 7
            'mergeData' => $mergeData,
399 7
        ];
400
401 7 View Code Duplication
        if (null !== $templateFilename) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
402 6
            $template = file_get_contents($templateFilename);
403 6
            $template = base64_encode($template);
404 6
            $json['template'] = $template;
405 6
        }
406
407 7
        if (count($mergeSettings) > 0) {
408 4
            $json['mergeSettings'] = $this->buildMergeSettingsArray($mergeSettings);
409 2
        }
410
411
        $options = [
412 5
            RequestOptions::QUERY => $query,
413 5
            RequestOptions::JSON  => $json,
414 5
        ];
415
416 5
        $response = $this->request('POST', $this->uri('/document/merge'), $options);
417
418 5
        if ($response instanceof Response && 200 === $response->getStatusCode()) {
419 5
            $body = json_decode($response->getBody(), true);
420 5 View Code Duplication
            if (is_array($body) && count($body) > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
421 5
                $ret = array_map('base64_decode', $body);
422 5
            }
423 5
        }
424
425 5
        return $ret;
426
    }
427
428
    /**
429
     * Perform find and replace in document and return binary data.
430
     *
431
     * @param array  $findAndReplaceData Array of find and replace data
432
     * @param string $returnFormat       Return format
433
     * @param string $templateName       Template name
434
     * @param string $templateFilename   Template filename on local file system
435
     * @param array  $mergeSettings      Array of merge settings
436
     *
437
     * @throws InvalidArgumentException
438
     *
439
     * @return null|string
440
     */
441 11
    public function findAndReplaceDocument($findAndReplaceData, $returnFormat, $templateName = null,
442
                                           $templateFilename = null, $mergeSettings = [])
443
    {
444 11
        $ret = null;
445
446 11
        StaticValidator::execute($findAndReplaceData, 'TypeArray');
447 11
        StaticValidator::execute($returnFormat      , 'ReturnFormat');
448
449 10
        if (null !== $templateName) {
450 2
            StaticValidator::execute($templateName, 'TemplateName');
451 1
        }
452
453 9 View Code Duplication
        if (null !== $templateFilename) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
454 8
            StaticValidator::execute($templateFilename, 'TemplateExtension');
455 5
            StaticValidator::execute($templateFilename, 'FileExists');
456 4
            $templateFilename = realpath($templateFilename);
457 5
        }
458
459 5
        StaticValidator::execute($mergeSettings, 'TypeArray');
460
461
        $query = [
462 4
            'returnFormat' => $returnFormat,
463 4
        ];
464
465 4
        if (null !== $templateName) {
466 1
            $query['templateName'] = $templateName;
467 1
        }
468
469
        $json = [
470 4
            'findAndReplaceData' => $this->buildFindAndReplaceDataArray($findAndReplaceData),
471 4
        ];
472
473 4 View Code Duplication
        if (null !== $templateFilename) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
474 3
            $template = file_get_contents($templateFilename);
475 3
            $template = base64_encode($template);
476 3
            $json['template'] = $template;
477 3
        }
478
479 4
        if (count($mergeSettings) > 0) {
480 4
            $json['mergeSettings'] = $this->buildMergeSettingsArray($mergeSettings);
481 2
        }
482
483
        $options = [
484 2
            RequestOptions::QUERY => $query,
485 2
            RequestOptions::JSON  => $json,
486 2
        ];
487
488 2
        $response = $this->request('POST', $this->uri('/document/findandreplace'), $options);
489
490 2
        if ($response instanceof Response && 200 === $response->getStatusCode()) {
491 2
            $ret  = base64_decode($response->getBody());
492 2
        }
493
494 2
        return $ret;
495
    }
496
497
498
    /**
499
     * DELETE methods
500
     * =================================================================================================================
501
     */
502
503
    /**
504
     * Delete a template in template storage
505
     *
506
     * @param string $templateName Template name
507
     *
508
     * @throws InvalidArgumentException
509
     *
510
     * @return bool
511
     */
512 11
    public function deleteTemplate($templateName)
513
    {
514 11
        $ret = false;
515
516 11
        StaticValidator::execute($templateName, 'TemplateName');
517
518
        $query = [
519 10
            'templateName' => $templateName,
520 10
        ];
521
522
        $options = [
523 10
            RequestOptions::QUERY => $query,
524 10
        ];
525
526 10
        $response = $this->request('DELETE', $this->uri('/templates/delete'), $options);
527
528 9
        if ($response instanceof Response && 204 === $response->getStatusCode()) {
529 9
            $ret = true;
530 9
        }
531
532 9
        return $ret;
533
    }
534
}