Completed
Push — master ( 160801...bd59d4 )
by Andreas
27:08
created

blobs::load()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4.016

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 4
nop 0
dl 0
loc 17
ccs 9
cts 10
cp 0.9
crap 4.016
rs 9.9332
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright CONTENT CONTROL GmbH, http://www.contentcontrol-berlin.de
4
 */
5
6
namespace midcom\datamanager\storage;
7
8
use Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser;
9
use midcom_db_attachment;
10
use midcom_error;
11
use midcom_connection;
12
use midcom;
13
use midcom\datamanager\helper\attachment;
14
15
/**
16
 * Experimental storage class
17
 */
18
class blobs extends delayed
19
{
20
    use attachment;
21
22
    /**
23
     *
24
     * @var midcom_db_attachment[]
25
     */
26
    protected $map = [];
27
28
    /**
29
     * @return midcom_db_attachment[]
30
     */
31 42
    public function load()
32
    {
33 42
        $results = [];
34 42
        if (!$this->object->id) {
35 9
            return $results;
36
        }
37
38 33
        $items = $this->load_attachment_list();
39 33
        foreach ($items as $identifier => $guid) {
40
            try {
41 4
                $results[$identifier] = new midcom_db_attachment($guid);
42
            } catch (midcom_error $e) {
43 4
                $e->log();
44
            }
45
        }
46
47 33
        return $results;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 1
    public function save()
54
    {
55 1
        $this->map = [];
56 1
        $atts_in_db = $this->load();
57
58 1
        if (!empty($this->value)) {
59 1
            $guesser = new FileBinaryMimeTypeGuesser;
60 1
            foreach ($this->value as $identifier => $att) {
61 1
                if (!is_a($att, midcom_db_attachment::class)) {
62
                    continue;
63
                }
64
65 1
                $db_att = (array_key_exists($identifier, $atts_in_db)) ? $atts_in_db[$identifier] : null;
66
67
                // new upload case
68 1
                if ($att->id === 0) {
69 1
                    $filename = midcom_db_attachment::safe_filename($att->name, true);
70 1
                    $title = $att->title ?: $att->name;
71 1
                    $source = $att->location;
72 1
                    $mimetype = $guesser->guess($source);
73
74 1
                    if (empty($db_att)) {
75 1
                        $db_att = $att;
76 1
                        $db_att->parentguid = $this->object->guid;
77 1
                        $this->create_attachment($db_att, $filename, $title, $mimetype);
78 1
                        $identifier = md5(time() . $db_att->name . $source);
79
                    } else {
80
                        $db_att->name = $filename;
81
                        $db_att->title = $title;
82
                        $db_att->mimetype = $mimetype;
83
                    }
84 1
                    if (!$db_att->copy_from_file($source)) {
85
                        throw new midcom_error('Failed to copy attachment: ' . midcom_connection::get_error_string());
86
                    }
87 1
                    unlink($source);
88
                }
89
                // No file upload, only title change
90 1
                elseif ($db_att->title != $att->title) {
91
                    $db_att->title = $att->title;
92
                    $db_att->update();
0 ignored issues
show
Bug introduced by
The method update() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

92
                    $db_att->/** @scrutinizer ignore-call */ 
93
                             update();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
93
                }
94 1
                $this->map[$identifier] = $db_att;
95 1
                if (!empty($this->config['widget_config']['sortable'])) {
96
                    $db_att->metadata->score = (int) $att->metadata->score;
97
                    $db_att->update();
98
                }
99 1
                if (!empty($this->config['widget_config']['show_description'])) {
100 1
                    $db_att->set_parameter('midcom.helper.datamanager2.type.blobs', 'description', $this->value['description']);
101
                }
102
            }
103
        }
104
        //delete attachments which are no longer in map
105 1
        foreach (array_diff_key($atts_in_db, $this->map) as $attachment) {
106
            $attachment->delete();
107
        }
108
109 1
        $this->save_attachment_list();
110 1
    }
111
112
    public function move_uploaded_files() : int
113
    {
114
        $total_moved = 0;
115
116
        foreach ($this->value as $att) {
117
            if (!is_a($att, midcom_db_attachment::class)) {
118
                continue;
119
            }
120
            if ($att->id !== 0) {
121
                continue;
122
            }
123
            $prefix = midcom::get()->config->get('midcom_tempdir') . '/tmpfile-';
124
            if (substr($att->location, 0, strlen($prefix)) === $prefix) {
125
                continue;
126
            }
127
            $total_moved++;
128
129
            $source = $att->location;
130
            $att->location = $prefix . md5(time() . $att->name . $source);
131
            $att->title = $att->name;
132
133
            move_uploaded_file($source, $att->location);
134
        }
135
136
        return $total_moved;
137
    }
138
139
    /**
140
     *
141
     * @return boolean
142
     */
143 2
    protected function save_attachment_list() : bool
144
    {
145 2
        if (!empty($this->config['widget_config']['sortable'])) {
146
            uasort($this->map, function ($a, $b) {
147
                if ($a->metadata->score == $b->metadata->score) {
148
                    return strnatcasecmp($a->name, $b->name);
149
                }
150
                return $b->metadata->score <=> $a->metadata->score;
151
            });
152
        }
153
154 2
        $list = [];
155
156 2
        foreach ($this->map as $identifier => $attachment) {
157 2
            $list[] = $identifier . ':' . $attachment->guid;
158
        }
159 2
        return $this->object->set_parameter('midcom.helper.datamanager2.type.blobs', "guids_{$this->config['name']}", implode(',', $list));
160
    }
161
162
    /**
163
     *
164
     * @return array
165
     */
166 33
    protected function load_attachment_list() : array
167
    {
168 33
        $map = [];
169 33
        $raw_list = $this->object->get_parameter('midcom.helper.datamanager2.type.blobs', "guids_{$this->config['name']}");
170 33
        if (!$raw_list) {
171 29
            return $map;
172
        }
173
174 4
        foreach (explode(',', $raw_list) as $item) {
175 4
            $info = explode(':', $item);
176 4
            if (count($info) < 2) {
177
                debug_add("item '{$item}' is broken!", MIDCOM_LOG_ERROR);
178
                continue;
179
            }
180 4
            $identifier = $info[0];
181 4
            $guid = $info[1];
182 4
            if (mgd_is_guid($guid)) {
183 4
                $map[$identifier] = $guid;
184
            }
185
        }
186 4
        return $map;
187
    }
188
}
189