Passed
Push — master ( 40aec1...d8787f )
by Andreas
11:30
created

blobs::save()   C

Complexity

Conditions 12
Paths 6

Size

Total Lines 57
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 15.7839

Importance

Changes 0
Metric Value
cc 12
eloc 37
c 0
b 0
f 0
nc 6
nop 0
dl 0
loc 57
ccs 26
cts 37
cp 0.7027
crap 15.7839
rs 6.9666

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
 * @copyright CONTENT CONTROL GmbH, http://www.contentcontrol-berlin.de
4
 */
5
6
namespace midcom\datamanager\storage;
7
8
use midcom_db_attachment;
9
use midcom_core_dbaobject;
10
use midcom_error;
11
use midcom_connection;
12
use midcom;
13
use midcom\datamanager\helper\attachment;
14
use Symfony\Component\Mime\FileBinaryMimeTypeGuesser;
15
16
/**
17
 * Experimental storage class
18
 */
19
class blobs extends delayed
20
{
21
    use attachment;
22
23
    /**
24
     * @var midcom_db_attachment[]
25
     */
26
    protected array $map = [];
27
28
    /**
29
     * @return midcom_db_attachment[]
30
     */
31 46
    public function load()
32
    {
33 46
        $results = [];
34 46
        if (!$this->object->id) {
35 11
            return $results;
36
        }
37
38 36
        $items = $this->load_attachment_list();
39 36
        foreach ($items as $identifier => $guid) {
40
            try {
41 4
                $results[$identifier] = new midcom_db_attachment($guid);
42
            } catch (midcom_error $e) {
43
                $e->log();
44
            }
45
        }
46
47 36
        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 (!($att instanceof midcom_db_attachment)) {
62
                    continue;
63
                }
64
65 1
                $db_att = $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);
70 1
                    $title = $att->title ?: $att->name;
71 1
                    $source = $att->location;
72 1
                    $mimetype = $guesser->guessMimeType($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);
0 ignored issues
show
Bug introduced by
It seems like $mimetype can also be of type null; however, parameter $mimetype of midcom\datamanager\stora...bs::create_attachment() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

77
                        $this->create_attachment($db_att, $filename, $title, /** @scrutinizer ignore-type */ $mimetype);
Loading history...
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 = $att->metadata->score;
97
                    $db_att->update();
98
                }
99 1
                if (!empty($this->config['widget_config']['show_description'])) {
100
                    $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
    }
111
112
    public function move_uploaded_files() : int
113
    {
114
        $total_moved = 0;
115
116
        foreach ($this->value as $att) {
117
            if (!($att instanceof midcom_db_attachment)) {
118
                continue;
119
            }
120
            if ($att->id !== 0) {
121
                continue;
122
            }
123
            $prefix = midcom::get()->config->get('midcom_tempdir') . '/tmpfile-';
124
            if (str_starts_with($att->location, $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 2
    protected function save_attachment_list() : bool
140
    {
141 2
        if (!empty($this->config['widget_config']['sortable'])) {
142
            uasort($this->map, function (midcom_db_attachment $a, midcom_db_attachment $b) {
143
                if ($a->metadata->score == $b->metadata->score) {
144
                    return strnatcasecmp($a->name, $b->name);
145
                }
146
                return $b->metadata->score <=> $a->metadata->score;
147
            });
148
        }
149
150 2
        $list = [];
151
152 2
        foreach ($this->map as $identifier => $attachment) {
153 2
            $list[] = $identifier . ':' . $attachment->guid;
154
        }
155 2
        return $this->object->set_parameter('midcom.helper.datamanager2.type.blobs', "guids_{$this->config['name']}", implode(',', $list));
156
    }
157
158 36
    protected function load_attachment_list() : array
159
    {
160 36
        return self::load_map($this->object, $this->config['name']);
161
    }
162
163 44
    private static function load_map(midcom_core_dbaobject $object, string $field) : array
164
    {
165 44
        $map = [];
166 44
        $raw_list = $object->get_parameter('midcom.helper.datamanager2.type.blobs', "guids_{$field}");
167 44
        if (!$raw_list) {
168 40
            return $map;
169
        }
170
171 4
        foreach (explode(',', $raw_list) as $item) {
172 4
            $info = explode(':', $item);
173 4
            if (count($info) < 2) {
174
                debug_add("item '{$item}' is broken!", MIDCOM_LOG_ERROR);
175
                continue;
176
            }
177 4
            [$identifier, $guid] = $info;
178 4
            if (mgd_is_guid($guid)) {
179 4
                $map[$identifier] = $guid;
180
            }
181
        }
182 4
        return $map;
183
    }
184
185
    /**
186
     * @return midcom_db_attachment[] List of attachments, indexed by identifier
187
     */
188 9
    public static function get_attachments(midcom_core_dbaobject $object, string $field) : array
189
    {
190 9
        $attachments = [];
191 9
        foreach (self::load_map($object, $field) as $identifier => $guid) {
192
            try {
193
                $attachments[$identifier] = midcom_db_attachment::get_cached($guid);
194
            } catch (midcom_error $e) {
195
                $e->log();
196
            }
197
        }
198 9
        return $attachments;
199
    }
200
}
201