Completed
Push — master ( dc16a8...a0dbc9 )
by Jonathan
04:38
created

ReportingCloud   B

Complexity

Total Complexity 51

Size/Duplication

Total Lines 527
Duplicated Lines 28.65 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 99.17%

Importance

Changes 11
Bugs 0 Features 0
Metric Value
wmc 51
c 11
b 0
f 0
lcom 1
cbo 9
dl 151
loc 527
ccs 238
cts 240
cp 0.9917
rs 8.3206

14 Methods

Rating   Name   Duplication   Size   Complexity  
A getTemplateInfo() 0 20 3
B getTemplateThumbnails() 3 26 3
A getTemplateCount() 0 4 1
A getTemplateList() 21 21 4
A getTemplatePageCount() 10 10 1
A templateExists() 10 10 1
A getAccountSettings() 21 21 4
A downloadTemplate() 0 18 2
A get() 0 17 3
B uploadTemplate() 31 31 3
B convertDocument() 32 32 3
C mergeDocument() 13 67 11
C findAndReplace() 10 64 9
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
 * Official wrapper (authored by Text Control GmbH, publisher of ReportingCloud) to access ReportingCloud in PHP.
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\BooleanToString as BooleanToStringFilter;
19
use TxTextControl\ReportingCloud\Filter\DateTimeToTimestamp as DateTimeToTimestampFilter;
20
use TxTextControl\ReportingCloud\PropertyMap\AccountSettings as AccountSettingsPropertyMap;
21
use TxTextControl\ReportingCloud\PropertyMap\TemplateInfo as TemplateInfoPropertyMap;
22
use TxTextControl\ReportingCloud\PropertyMap\TemplateList as TemplateListPropertyMap;
23
use TxTextControl\ReportingCloud\Validator\StaticValidator;
24
25
/**
26
 * ReportingCloud
27
 *
28
 * @package TxTextControl\ReportingCloud
29
 * @author  Jonathan Maron (@JonathanMaron)
30
 */
31
class ReportingCloud extends AbstractReportingCloud
32
{
33
    use ReportingCloudTrait;
34
35
    /**
36
     * GET methods
37
     * =================================================================================================================
38
     */
39
40
    /**
41
     * Return an array of merge blocks and merge fields in a template file in template storage.
42
     *
43
     * @param string  $templateName Template name
44
     *
45
     * @throws InvalidArgumentException
46
     *
47
     * @return array|null
48 1
     */
49
    public function getTemplateInfo($templateName)
50 1
    {
51
        $ret = null;
52 1
53
        $propertyMap = new TemplateInfoPropertyMap();
54 1
55
        StaticValidator::execute($templateName, 'TemplateName');
56
57 1
        $query = [
58 1
            'templateName' => $templateName,
59
        ];
60 1
61
        $records = $this->get('/templates/info', $query);
62 1
63 1
        if (is_array($records) && count($records) > 0) {
64 1
            $ret = $this->buildPropertyMapArray($records, $propertyMap);
65
        }
66 1
67
        return $ret;
68
    }
69
70
    /**
71
     * Return an array of binary data.
72
     * Each record in the array is the binary data of a thumbnail image
73
     *
74
     * @param string  $templateName Template name
75
     * @param integer $zoomFactor   Zoom factor
76
     * @param integer $fromPage     From page
77
     * @param integer $toPage       To page
78
     * @param string  $imageFormat  Image format
79
     *
80
     * @throws InvalidArgumentException
81
     *
82
     * @return array|null
83 6
     */
84
    public function getTemplateThumbnails($templateName, $zoomFactor, $fromPage, $toPage, $imageFormat)
85 6
    {
86
        $ret = null;
87 6
88 5
        StaticValidator::execute($templateName, 'TemplateName');
89 4
        StaticValidator::execute($zoomFactor  , 'ZoomFactor');
90 3
        StaticValidator::execute($fromPage    , 'Page');
91 2
        StaticValidator::execute($toPage      , 'Page');
92
        StaticValidator::execute($imageFormat , 'ImageFormat');
93
94 1
        $query = [
95 1
            'templateName' => $templateName,
96 1
            'zoomFactor'   => $zoomFactor,
97 1
            'fromPage'     => $fromPage,
98 1
            'toPage'       => $toPage,
99 1
            'imageFormat'  => $imageFormat,
100
        ];
101 1
102
        $records = $this->get('/templates/thumbnails', $query);
103 1
104 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...
105 1
            $ret = array_map('base64_decode', $records);
106 1
        }
107 1
108 1
        return $ret;
109
    }
110 1
111
    /**
112
     * Return the number of templates in template storage
113
     *
114
     * @return integer|null
115
     */
116
    public function getTemplateCount()
117
    {
118 1
        return $this->get('/templates/count');
119
    }
120 1
121
    /**
122
     * Return an array properties for the templates in template storage
123
     *
124
     * @return array|null
125
     */
126 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...
127
    {
128 1
        $ret = null;
129
130 1
        $propertyMap = new TemplateListPropertyMap();
131
        $filter      = new DateTimeToTimestampFilter();
132 1
133 1
        $records = $this->get('/templates/list');
134
135 1
        if (is_array($records) && count($records) > 0) {
136
            $ret = $this->buildPropertyMapArray($records, $propertyMap);
137 1
            array_walk($ret, function (&$record) use ($filter) {
138 1
                $key = 'modified';
139 1
                if (isset($record[$key])) {
140 1
                    $filter->filter($record[$key]);
141 1
                }
142 1
            });
143 1
        }
144 1
145 1
        return $ret;
146
    }
147 1
148
    /**
149
     * Return the number of pages in a template in template storage
150
     *
151
     * @param string $templateName Template name
152
     *
153
     * @throws InvalidArgumentException
154
     *
155
     * @return bool
156
     */
157 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...
158
    {
159 2
        StaticValidator::execute($templateName, 'TemplateName');
160
161 2
        $query = [
162
            'templateName' => $templateName,
163
        ];
164 1
165 1
        return (integer) $this->get('/templates/pagecount', $query);
166
    }
167 1
168
    /**
169
     * Return true, if the template exists in template storage
170
     *
171
     * @param string $templateName Template name
172
     *
173
     * @throws InvalidArgumentException
174
     *
175
     * @return bool
176
     */
177 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...
178
    {
179 2
        StaticValidator::execute($templateName, 'TemplateName');
180
181 2
        $query = [
182
            'templateName' => $templateName,
183
        ];
184 1
185 1
        return (boolean) $this->get('/templates/exists', $query);
186
    }
187 1
188
    /**
189
     * Return an array properties for the ReportingCloud account
190
     *
191
     * @return array|null
192
     */
193 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...
194
    {
195 3
        $ret = null;
196
197 3
        $propertyMap = new AccountSettingsPropertyMap();
198
        $filter      = new DateTimeToTimestampFilter();
199 3
200 3
        $records = $this->get('/account/settings');
201
202 3
        if (is_array($records) && count($records) > 0) {
203
            $ret = $this->buildPropertyMapArray($records, $propertyMap);
204 3
            array_walk($ret, function (&$record) use ($filter) {
205 3
                $key = 'valid_until';
206 3
                if (isset($record[$key])) {
207 3
                    $filter->filter($record[$key]);
208 3
                }
209
            });
210
        }
211 3
212 3
        return $ret;
213
    }
214 3
215
    /**
216
     * Download the binary data of a template from template storage
217
     *
218
     * @param string $templateName Template name
219
     *
220
     * @throws InvalidArgumentException
221
     *
222
     * @return null|resource
223
     */
224
    public function downloadTemplate($templateName)
225
    {
226 2
        $ret = null;
227
228 2
        StaticValidator::execute($templateName, 'TemplateName');
229
230 2
        $query = [
231
            'templateName' => $templateName,
232
        ];
233 1
234 1
        $data = $this->get('/templates/download', $query);
235
236 1
        if (null !== $data) {
237
            $ret = base64_decode($data);
238 1
        }
239 1
240 1
        return $ret;
241
    }
242 1
243
    /**
244
     * Execute a GET request via REST client
245
     *
246
     * @param string $uri   URI
247
     * @param array  $query Query
248
     *
249
     * @return mixed|null
250
     */
251
    protected function get($uri, $query = [])
252
    {
253 10
        $ret = null;
254
255 10
        $options = [
256
            RequestOptions::QUERY => $query,
257
        ];
258 10
259 10
        $response = $this->request('GET', $this->uri($uri), $options);
260
261 10
        if ($response instanceof Response && 200 === $response->getStatusCode()) {
262
            $body = (string) $response->getBody();
263 10
            $ret  = json_decode($body, true);
264 10
        }
265 10
266 10
        return $ret;
267 10
    }
268 10
269
270 10
    /**
271
     * POST methods
272
     * =================================================================================================================
273
     */
274
275
    /**
276
     * Upload a template to template storage
277
     *
278
     * @param string $templateFilename Template name
279
     *
280
     * @throws InvalidArgumentException
281
     *
282
     * @return bool
283
     */
284 View Code Duplication
    public function uploadTemplate($templateFilename)
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...
285
    {
286
        $ret = false;
287
288 13
        StaticValidator::execute($templateFilename, 'TemplateExtension');
289
        StaticValidator::execute($templateFilename, 'FileExists');
290 13
291
        $templateFilename = realpath($templateFilename);
292 13
        $templateName     = basename($templateFilename);
293 10
294
        $query = [
295 9
            'templateName' => $templateName,
296 9
        ];
297
298
        $body = file_get_contents($templateFilename);
299 9
        $body = base64_encode($body);
300 9
        $body = json_encode($body);
301
302 9
        $options = [
303 9
            RequestOptions::QUERY => $query,
304 9
            RequestOptions::BODY  => $body,
305
        ];
306
307 9
        $response = $this->request('POST', $this->uri('/templates/upload'), $options);
308 9
309 9
        if ($response instanceof Response && 201 === $response->getStatusCode()) {
310
            $ret = true;
311 9
        }
312
313 9
        return $ret;
314 9
    }
315 9
316 9
    /**
317 9
     * Convert a document on the local file system to a different format
318
     *
319 9
     * @param string $documentFilename Document filename
320
     * @param string $returnFormat     Return format
321
     *
322
     * @throws InvalidArgumentException
323
     *
324
     * @return null|resource
325
     */
326 View Code Duplication
    public function convertDocument($documentFilename, $returnFormat)
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...
327
    {
328
        $ret = null;
329
330
        StaticValidator::execute($documentFilename, 'DocumentExtension');
331
        StaticValidator::execute($documentFilename, 'FileExists');
332 6
        StaticValidator::execute($returnFormat    , 'ReturnFormat');
333
334 6
        $query = [
335
            'returnFormat' => $returnFormat,
336 6
        ];
337 3
338 2
        $documentFilename = realpath($documentFilename);
339
340 1
        $body = file_get_contents($documentFilename);
341
        $body = base64_encode($body);
342
        $body = json_encode($body);
343 1
344 1
        $options = [
345 1
            RequestOptions::QUERY => $query,
346
            RequestOptions::BODY  => $body,
347 1
        ];
348
349 1
        $response = $this->request('POST', $this->uri('/document/convert'), $options);
350 1
351 1
        if ($response instanceof Response && 200 === $response->getStatusCode()) {
352
            $body = (string) $response->getBody();
353
            $ret  = base64_decode($body);
354 1
        }
355 1
356 1
        return $ret;
357
    }
358 1
359
    /**
360 1
     * Merge data into a template and return an array of binary data.
361 1
     * Each record in the array is the binary data of one document
362 1
     *
363 1
     * @param array   $mergeData        Array of merge data
364 1
     * @param string  $returnFormat     Return format
365 1
     * @param string  $templateName     Template name
366
     * @param string  $templateFilename Template filename on local file system
367 1
     * @param boolean $append           Append flag
368
     * @param array   $mergeSettings    Array of merge settings
369
     *
370
     * @throws InvalidArgumentException
371
     *
372
     * @return null|string
373
     */
374
    public function mergeDocument($mergeData, $returnFormat, $templateName = null, $templateFilename = null,
375
                                    $append = null, $mergeSettings = [])
376
    {
377
        $ret = null;
378
379
        StaticValidator::execute($mergeData   , 'TypeArray');
380
        StaticValidator::execute($returnFormat, 'ReturnFormat');
381
382
        if (null !== $templateName) {
383
            StaticValidator::execute($templateName, 'TemplateName');
384
        }
385 15
386 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...
387
            StaticValidator::execute($templateFilename, 'TemplateExtension');
388 15
            StaticValidator::execute($templateFilename, 'FileExists');
389
            $templateFilename = realpath($templateFilename);
390 15
        }
391 15
392
        if (null !== $append) {
393 14
            $filter = new BooleanToStringFilter();
394 2
            $append = $filter->filter($append);
0 ignored issues
show
Documentation introduced by
$append is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
395 1
        }
396
397 13
        StaticValidator::execute($mergeSettings, 'TypeArray');
398 12
399 9
        $query = [
400 8
            'returnFormat' => $returnFormat,
401 8
            'append'       => $append,
402
        ];
403 9
404
        if (null !== $templateName) {
405 9
            $query['templateName'] = $templateName;
406 6
        }
407 5
408
        $body = [
409 8
            'mergeData' => $mergeData,
410
        ];
411
412 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...
413 7
            $template = file_get_contents($templateFilename);
414 7
            $template = base64_encode($template);
415 7
            $body['template'] = $template;
416
        }
417 7
418 1
        if (count($mergeSettings) > 0) {
419 1
            $body['mergeSettings'] = $this->buildMergeSettingsArray($mergeSettings);
420
        }
421
422 7
        $body = json_encode($body);
423 7
424
        $options = [
425 7
            RequestOptions::QUERY => $query,
426 6
            RequestOptions::BODY  => $body,
427 6
        ];
428 6
429 6
        $response = $this->request('POST', $this->uri('/document/merge'), $options);
430
431 7
        if ($response instanceof Response && 200 === $response->getStatusCode()) {
432 4
            $body = (string) $response->getBody();
433 2
            $body = json_decode($body, true);
434 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...
435 5
                $ret = array_map('base64_decode', $body);
436
            }
437
        }
438 5
439 5
        return $ret;
440 5
    }
441
442 5
    /**
443
     * Perform find and replace in template and return binary data.
444 5
     *
445 5
     * @param array  $findAndReplaceData Array of find and replace data
446 5
     * @param string $returnFormat       Return format
447 5
     * @param string $templateName       Template name
448 5
     * @param string $templateFilename   Template filename on local file system
449 5
     * @param array  $mergeSettings      Array of merge settings
450 5
     *
451 5
     * @throws InvalidArgumentException
452 5
     *
453 5
     * @return null|string
454 6
     */
455 5
    public function findAndReplace($findAndReplaceData, $returnFormat, $templateName = null, $templateFilename = null,
456
                                   $mergeSettings = [])
457 5
    {
458
        $ret = null;
459
460
        StaticValidator::execute($findAndReplaceData, 'TypeArray');
461
        StaticValidator::execute($returnFormat      , 'ReturnFormat');
462
463
        if (null !== $templateName) {
464
            StaticValidator::execute($templateName, 'TemplateName');
465
        }
466
467 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...
468
            StaticValidator::execute($templateFilename, 'TemplateExtension');
469
            StaticValidator::execute($templateFilename, 'FileExists');
470
            $templateFilename = realpath($templateFilename);
471
        }
472
473 11
        StaticValidator::execute($mergeSettings, 'TypeArray');
474
475
        $query = [
476 11
            'returnFormat' => $returnFormat,
477
        ];
478 11
479 11
        if (null !== $templateName) {
480
            $query['templateName'] = $templateName;
481 10
        }
482 2
483 1
        $findAndReplaceDataRc = [];
484
        foreach ($findAndReplaceData as $key => $value) {
485 9
            array_push($findAndReplaceDataRc, [$key, $value]);
486 8
        }
487 5
        unset($findAndReplaceData);
488 4
489 4
        $body = [
490
            'findAndReplaceData' => $findAndReplaceDataRc,
491 5
        ];
492
493 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...
494
            $template = file_get_contents($templateFilename);
495
            $template = base64_encode($template);
496 4
            $body['template'] = $template;
497 4
        }
498 4
499
        if (count($mergeSettings) > 0) {
500 4
            $body['mergeSettings'] = $this->buildMergeSettingsArray($mergeSettings);
501 1
        }
502 1
503
        $body = json_encode($body);
504 4
505 4
        $options = [
506 4
            RequestOptions::QUERY => $query,
507 4
            RequestOptions::BODY  => $body,
508 4
        ];
509
510
        $response = $this->request('POST', $this->uri('/document/findandreplace'), $options);
511 4
512 4
        if ($response instanceof Response && 200 === $response->getStatusCode()) {
513
            $body = (string) $response->getBody();
514 4
            $ret  = base64_decode($body);
515 3
        }
516 3
517 3
        return $ret;
518 3
    }
519
520 4
521 4
    /**
522 2
     * DELETE methods
523
     * =================================================================================================================
524 2
     */
525
526
    /**
527 2
     * Delete a template in template storage
528 2
     *
529 2
     * @param string $templateName Template name
530
     *
531 2
     * @throws InvalidArgumentException
532
     *
533 2
     * @return bool
534 2
     */
535 2
    public function deleteTemplate($templateName)
536 2
    {
537 2
        $ret = false;
538 2
539
        StaticValidator::execute($templateName, 'TemplateName');
540 2
541
        $query = [
542
            'templateName' => $templateName,
543
        ];
544
545
        $options = [
546
            RequestOptions::QUERY => $query,
547
        ];
548
549
        $response = $this->request('DELETE', $this->uri('/templates/delete'), $options);
550
551
        if ($response instanceof Response && 204 === $response->getStatusCode()) {
552
            $ret = true;
553
        }
554
555
        return $ret;
556
    }
557
}