Passed
Push — master ( 51c2a5...5c54bc )
by Petr
08:51
created

TStreamToPos::addStreamToPosition()   C

Complexity

Conditions 16
Paths 20

Size

Total Lines 88
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 16

Importance

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

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 8
    public function addStreamToPosition($original, $added, ?int $offset = null)
26
    {
27 8
        if (!is_null($offset)) {
28
            // put it somewhere, left the rest intact
29 6
            $originalStat = fstat($original);
30 6
            if (false === $originalStat) {
31
                // @codeCoverageIgnoreStart
32
                throw new FilesException($this->getFlLang()->flCannotOpenFile('temp'));
33
            }
34
            // @codeCoverageIgnoreEnd
35 6
            $originalLength = $originalStat['size'];
36
37 6
            $addedStat = fstat($added);
38 6
            if (false === $addedStat) {
39
                // @codeCoverageIgnoreStart
40
                throw new FilesException($this->getFlLang()->flCannotOpenFile('temp'));
41
            }
42
            // @codeCoverageIgnoreEnd
43 6
            $addedLength = $addedStat['size'];
44
45
            // original data in the beginning
46 6
            $destination = fopen('php://temp', 'rb+'); // the target storage
47 6
            if (false === $destination) {
48
                // @codeCoverageIgnoreStart
49
                throw new FilesException($this->getFlLang()->flCannotOpenFile('temp'));
50
            }
51
            // @codeCoverageIgnoreEnd
52 6
            if ((0 !== $offset) && (false === stream_copy_to_stream($original, $destination, $offset, 0))) {
53
                // @codeCoverageIgnoreStart
54
                throw new FilesException($this->getFlLang()->flCannotWriteFile('temp'));
55
            }
56
            // @codeCoverageIgnoreEnd
57
58
            // filler - when the size is too much
59 6
            if ($originalLength < $offset) {
60 2
                $begin = fopen('php://temp', 'rb+');
61 2
                if (false === $begin) {
62
                    // @codeCoverageIgnoreStart
63
                    throw new FilesException($this->getFlLang()->flCannotOpenFile('temp'));
64
                }
65
                // @codeCoverageIgnoreEnd
66 2
                /** @scrutinizer ignore-unhandled */@fwrite($begin, str_repeat("\0", intval(abs($offset - $originalLength))));
67 2
                /** @scrutinizer ignore-unhandled */@rewind($begin);
68 2
                if (false === stream_copy_to_stream($begin, $destination, -1, 0)) {
69
                    // @codeCoverageIgnoreStart
70
                    throw new FilesException($this->getFlLang()->flCannotWriteFile('temp'));
71
                }
72
                // @codeCoverageIgnoreEnd
73
74 2
                $beginStat = fstat($begin);
75 2
                if (false === $beginStat) {
76
                    // @codeCoverageIgnoreStart
77
                    throw new FilesException($this->getFlLang()->flCannotOpenFile('temp'));
78
                }
79
                // @codeCoverageIgnoreEnd
80 2
                $originalLength += $beginStat['size'];
81
            }
82
83
            // amended data itself
84 6
            if (false === stream_copy_to_stream($added, $destination, -1, 0)) {
85
                // @codeCoverageIgnoreStart
86
                throw new FilesException($this->getFlLang()->flCannotWriteFile('temp'));
87
            }
88
            // @codeCoverageIgnoreEnd
89
90
            // the rest from the original
91 6
            if ($originalLength > $offset + $addedLength) {
92 2
                $rest = fopen('php://temp', 'rb+'); // the temporary storage for the end
93 2
                if (false === $rest) {
94
                    // @codeCoverageIgnoreStart
95
                    throw new FilesException($this->getFlLang()->flCannotOpenFile('temp'));
96
                }
97
                // @codeCoverageIgnoreEnd
98 2
                if (false === stream_copy_to_stream($original, $rest, -1, $offset + $addedLength)) {
99
                    // @codeCoverageIgnoreStart
100
                    throw new FilesException($this->getFlLang()->flCannotWriteFile('temp'));
101
                }
102
                /** @scrutinizer ignore-unhandled */@rewind($rest);
103
                // @codeCoverageIgnoreEnd
104 2
                if (false === stream_copy_to_stream($rest, $destination, -1, 0)) {
105
                    // @codeCoverageIgnoreStart
106
                    throw new FilesException($this->getFlLang()->flCannotWriteFile('temp'));
107
                }
108
                // @codeCoverageIgnoreEnd
109
            }
110 6
            return $destination;
111
        } else {
112 2
            return $added;
113
        }
114
    }
115
}
116