Completed
Push — master ( a8faaf...37ee2c )
by Eric
08:05
created

Base64FileTrait::load()   C

Complexity

Conditions 7
Paths 16

Size

Total Lines 34
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 23
cts 23
cp 1
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 21
nc 16
nop 2
crap 7
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 string
21
     */
22
    private $path;
23
24
    /**
25
     * @var resource
26
     */
27
    private $resource;
28
29
    /**
30
     * {@inheritdoc}
31
     */
32 318
    public function __destruct()
33
    {
34 318
        if (is_resource($this->resource)) {
35 318
            fclose($this->resource);
36 248
        }
37
38 318
        if (file_exists($this->path)) {
39 318
            unlink($this->path);
40 248
        }
41 318
    }
42
43
    /**
44
     * @param bool $encoded
45
     * @param bool $asResource
46
     *
47
     * @return resource|string
48
     */
49 315
    public function getData($encoded = true, $asResource = true)
50
    {
51 315
        $resource = fopen('php://temp', 'rb+');
52
53 315
        if ($encoded) {
54 171
            $filter = stream_filter_append($resource, 'convert.base64-encode', STREAM_FILTER_WRITE);
55 133
        }
56
57 315
        $this->copyStreamToStream($this->resource, $resource);
58
59 315
        if (isset($filter)) {
60 171
            stream_filter_remove($filter);
61 133
        }
62
63 315
        if ($asResource) {
64 144
            return $resource;
65
        }
66
67 171
        $content = stream_get_contents($resource);
68 171
        fclose($resource);
69
70 171
        return $content;
71
    }
72
73
    /**
74
     * @param string|resource $value
75
     * @param bool            $encoded
76
     *
77
     * @return string
78
     */
79 405
    private function load($value, $encoded = true)
80
    {
81 405
        $this->path = tempnam(sys_get_temp_dir(), 'ivory_base64');
82 405
        $this->resource = fopen($this->path, 'w+');
83
84 405
        if ($encoded) {
85 261
            $filter = stream_filter_append($this->resource, 'convert.base64-decode', STREAM_FILTER_WRITE);
86 203
        }
87
88
        try {
89 405
            if (is_string($value)) {
90 198
                $this->copyStringToStream($value, $this->resource);
91 340
            } elseif (is_resource($value)) {
92 189
                $this->copyStreamToStream($value, $this->resource);
93 133
            } else {
94 18
                throw new \InvalidArgumentException(sprintf(
95 18
                    'The base64 file value must be a string or a resource, got "%s".',
96 94
                    is_object($value) ? get_class($value) : gettype($value)
97 14
                ));
98
            }
99 329
        } catch (\Exception $e) {
100 63
            fclose($this->resource);
101
102 63
            throw $e;
103
        }
104
105 342
        if (isset($filter)) {
106 198
            stream_filter_remove($filter);
107 154
        }
108
109 342
        fflush($this->resource);
110
111 342
        return $this->path;
112
    }
113
114
    /**
115
     * @param string   $from
116
     * @param resource $to
117
     */
118 198
    private function copyStringToStream($from, $to)
119
    {
120 198
        $toPosition = ftell($to);
121 198
        $success = @fwrite($to, $from);
122 198
        fseek($to, $toPosition);
123
124 198 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...
125 27
            $error = error_get_last();
126
127 27
            throw new \RuntimeException(sprintf(
128 27
                'An error occurred while copying the value (%s).',
129 27
                $error['message']
130 21
            ));
131
        }
132 171
    }
133
134
    /**
135
     * @param resource $from
136
     * @param resource $to
137
     */
138 360
    private function copyStreamToStream($from, $to)
139
    {
140 360
        $metadata = stream_get_meta_data($from);
141 360
        $seekable = $metadata['seekable'];
142
143 360
        $toPosition = ftell($to);
144
145 360
        if ($seekable) {
146 360
            $fromPosition = ftell($from);
147 360
            rewind($from);
148 280
        }
149
150 360
        $success = @stream_copy_to_stream($from, $to);
151
152 360
        if (isset($fromPosition)) {
153 360
            fseek($from, $fromPosition);
154 280
        }
155
156 360
        fseek($to, $toPosition);
157
158 360 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...
159 18
            $error = error_get_last();
160
161 18
            throw new \RuntimeException(sprintf(
162 18
                'An error occurred while copying the value (%s).',
163 18
                $error['message']
164 14
            ));
165
        }
166 342
    }
167
}
168