Passed
Push — master ( fba3db...2b14a7 )
by Petr
03:12
created

TStreamToPos::addStreamToPosition()   C

Complexity

Conditions 16
Paths 20

Size

Total Lines 88
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 21.324

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 16
eloc 40
c 1
b 0
f 0
nc 20
nop 3
dl 0
loc 88
ccs 29
cts 40
cp 0.725
crap 21.324
rs 5.5666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace kalanis\kw_files\Traits;
4
5
6
use kalanis\kw_files\FilesException;
7
8
9
/**
10
 * Trait TStreamToPos
11
 * @package kalanis\kw_menu\Traits
12
 * Write stream at expected position
13
 */
14
trait TStreamToPos
15
{
16
    use TLang;
17
18
    /**
19
     * @param resource $original stream with original content, usually file handler
20
     * @param resource $added stream with what will be added, also file handler
21
     * @param int|null $offset where it will be added
22
     * @throws FilesException
23
     * @return resource
24
     */
25 12
    public function addStreamToPosition($original, $added, ?int $offset = null)
26
    {
27 12
        if (!is_null($offset)) {
28
            // put it somewhere, left the rest intact
29 10
            $originalStat = fstat($original);
30 10
            if (false === $originalStat) {
31
                // @codeCoverageIgnoreStart
32
                throw new FilesException($this->getLang()->flCannotOpenFile('temp'));
33
            }
34
            // @codeCoverageIgnoreEnd
35 10
            $originalLength = $originalStat['size'];
36
37 10
            $addedStat = fstat($added);
38 10
            if (false === $addedStat) {
39
                // @codeCoverageIgnoreStart
40
                throw new FilesException($this->getLang()->flCannotOpenFile('temp'));
41
            }
42
            // @codeCoverageIgnoreEnd
43 10
            $addedLength = $addedStat['size'];
44
45
            // original data in the beginning
46 10
            $destination = fopen('php://temp', 'rb+'); // the target storage
47 10
            if (false === $destination) {
48
                // @codeCoverageIgnoreStart
49
                throw new FilesException($this->getLang()->flCannotOpenFile('temp'));
50
            }
51
            // @codeCoverageIgnoreEnd
52 10
            if ((0 !== $offset) && (false === stream_copy_to_stream($original, $destination, $offset, 0))) {
53
                // @codeCoverageIgnoreStart
54
                throw new FilesException($this->getLang()->flCannotWriteFile('temp'));
55
            }
56
            // @codeCoverageIgnoreEnd
57
58
            // filler - when the size is too much
59 10
            if ($originalLength < $offset) {
60 6
                $begin = fopen('php://temp', 'rb+');
61 6
                if (false === $begin) {
62
                    // @codeCoverageIgnoreStart
63
                    throw new FilesException($this->getLang()->flCannotOpenFile('temp'));
64
                }
65
                // @codeCoverageIgnoreEnd
66 6
                /** @scrutinizer ignore-unhandled */@fwrite($begin, str_repeat("\0", intval(abs($offset - $originalLength))));
67 6
                /** @scrutinizer ignore-unhandled */@rewind($begin);
68 6
                if (false === stream_copy_to_stream($begin, $destination, -1, 0)) {
69
                    // @codeCoverageIgnoreStart
70
                    throw new FilesException($this->getLang()->flCannotWriteFile('temp'));
71
                }
72
                // @codeCoverageIgnoreEnd
73
74 6
                $beginStat = fstat($begin);
75 6
                if (false === $beginStat) {
76
                    // @codeCoverageIgnoreStart
77
                    throw new FilesException($this->getLang()->flCannotOpenFile('temp'));
78
                }
79
                // @codeCoverageIgnoreEnd
80 6
                $originalLength += $beginStat['size'];
81
            }
82
83
            // amended data itself
84 10
            if (false === stream_copy_to_stream($added, $destination, -1, 0)) {
85
                // @codeCoverageIgnoreStart
86
                throw new FilesException($this->getLang()->flCannotWriteFile('temp'));
87
            }
88
            // @codeCoverageIgnoreEnd
89
90
            // the rest from the original
91 10
            if ($originalLength > $offset + $addedLength) {
92 4
                $rest = fopen('php://temp', 'rb+'); // the temporary storage for the end
93 4
                if (false === $rest) {
94
                    // @codeCoverageIgnoreStart
95
                    throw new FilesException($this->getLang()->flCannotOpenFile('temp'));
96
                }
97
                // @codeCoverageIgnoreEnd
98 4
                if (false === stream_copy_to_stream($original, $rest, -1, $offset + $addedLength)) {
99
                    // @codeCoverageIgnoreStart
100
                    throw new FilesException($this->getLang()->flCannotWriteFile('temp'));
101
                }
102 4
                /** @scrutinizer ignore-unhandled */@rewind($rest);
103
                // @codeCoverageIgnoreEnd
104 4
                if (false === stream_copy_to_stream($rest, $destination, -1, 0)) {
105
                    // @codeCoverageIgnoreStart
106
                    throw new FilesException($this->getLang()->flCannotWriteFile('temp'));
107
                }
108
                // @codeCoverageIgnoreEnd
109
            }
110 10
            return $destination;
111
        } else {
112 2
            return $added;
113
        }
114
    }
115
}
116