Completed
Push — master ( 81f3f7...0d8dc5 )
by Eric
08:43
created

Base64FileTrait::load()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 31
ccs 22
cts 22
cp 1
rs 8.439
c 0
b 0
f 0
cc 6
eloc 19
nc 16
nop 2
crap 6
1
<?php
2
3
/*
4
 * This file is part of the Ivory Base64 File package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ivory\Base64FileBundle\Model;
13
14
/**
15
 * @author GeLo <[email protected]>
16
 */
17
trait Base64FileTrait
18
{
19
    /**
20
     * @var resource
21
     */
22
    private $resource;
23
24
    /**
25
     * @param string|resource $value
26
     * @param bool            $encoded
27
     */
28 675
    private function load($value, $encoded = true)
29
    {
30 675
        $this->resource = tmpfile();
31
32 675
        if ($encoded) {
33 435
            $filter = stream_filter_append($this->resource, 'convert.base64-decode', STREAM_FILTER_WRITE);
34 406
        }
35
36
        try {
37 675
            if (is_string($value)) {
38 330
                $this->copyStringToStream($value, $this->resource);
39 611
            } elseif (is_resource($value)) {
40 315
                $this->copyStreamToStream($value, $this->resource);
41 266
            } else {
42 30
                throw new \InvalidArgumentException(sprintf(
43 68
                    'The base64 file value must be a string or a resource, got "%s".',
44 28
                    gettype($value)
45 28
                ));
46
            }
47 637
        } catch (\Exception $e) {
48 105
            fclose($this->resource);
49
50 105
            throw $e;
51
        }
52
53 570
        if (isset($filter)) {
54 330
            stream_filter_remove($filter);
55 308
        }
56
57 570
        fflush($this->resource);
58 570
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63 535
    public function __destruct()
64
    {
65 535
        if (is_resource($this->resource)) {
66 535
            fclose($this->resource);
67 499
        }
68 535
    }
69
70
    /**
71
     * @param bool $encoded
72
     * @param bool $asResource
73
     *
74
     * @return resource|string
75
     */
76 525
    public function getData($encoded = true, $asResource = true)
77
    {
78 525
        $resource = fopen('php://temp', 'rb+');
79
80 525
        if ($encoded) {
81 285
            $filter = stream_filter_append($resource, 'convert.base64-encode', STREAM_FILTER_WRITE);
82 266
        }
83
84 525
        $this->copyStreamToStream($this->resource, $resource);
85
86 525
        if (isset($filter)) {
87 285
            stream_filter_remove($filter);
88 266
        }
89
90 525
        if ($asResource) {
91 240
            return $resource;
92
        }
93
94 285
        $content = stream_get_contents($resource);
95 285
        fclose($resource);
96
97 285
        return $content;
98
    }
99
100
    /**
101
     * @param string   $from
102
     * @param resource $to
103
     */
104 330
    private function copyStringToStream($from, $to)
105
    {
106 330
        $toPosition = ftell($to);
107 330
        $success = @fwrite($to, $from);
108 330
        fseek($to, $toPosition);
109
110 330 View Code Duplication
        if (!$success) {
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...
111 45
            $error = error_get_last();
112
113 45
            throw new \RuntimeException(sprintf(
114 45
                'An error occurred while copying the value (%s).',
115 45
                $error['message']
116 42
            ));
117
        }
118 285
    }
119
120
    /**
121
     * @param resource $from
122
     * @param resource $to
123
     */
124 600
    private function copyStreamToStream($from, $to)
125
    {
126 600
        $metadata = stream_get_meta_data($from);
127 600
        $seekable = $metadata['seekable'];
128
129 600
        $toPosition = ftell($to);
130
131 600
        if ($seekable) {
132 600
            $fromPosition = ftell($from);
133 600
            rewind($from);
134 560
        }
135
136 600
        $success = @stream_copy_to_stream($from, $to);
137
138 600
        if (isset($fromPosition)) {
139 600
            fseek($from, $fromPosition);
140 560
        }
141
142 600
        fseek($to, $toPosition);
143
144 600 View Code Duplication
        if (!$success) {
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...
145 30
            $error = error_get_last();
146
147 30
            throw new \RuntimeException(sprintf(
148 30
                'An error occurred while copying the value (%s).',
149 30
                $error['message']
150 28
            ));
151
        }
152 570
    }
153
}
154