Failed Conditions
Pull Request — master (#263)
by Maximo
03:19
created

FileManagementTrait::getById()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 12
ccs 0
cts 9
cp 0
crap 6
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Canvas\Traits;
6
7
use Phalcon\Http\Response;
8
use Phalcon\Validation;
9
use Phalcon\Validation\Validator\File as FileValidator;
10
use Canvas\Exception\UnprocessableEntityHttpException;
11
use Canvas\Models\FileSystem;
12
use Canvas\Filesystem\Helper;
13
use Baka\Http\QueryParser;
14
use Canvas\Http\Exception\UnprocessableEntityException;
15
use Canvas\Models\FileSystemSettings;
16
use Canvas\Models\SystemModules;
17
use Canvas\Models\FileSystemEntities;
18
19
/**
20
 * Trait ResponseTrait.
21
 *
22
 * @package Canvas\Traits
23
 *
24
 * @property Users $user
25
 * @property AppsPlans $appPlan
26
 * @property CompanyBranches $branches
27
 * @property Companies $company
28
 * @property UserCompanyApps $app
29
 * @property \Phalcon\Di $di
30
 *
31
 */
32
trait FileManagementTrait
33
{
34
    /**
35
     * Add a new item.
36
     *
37
     * @method POST
38
     * url /v1/filesystem
39
     *
40
     * @return \Phalcon\Http\Response
41
     * @throws Exception
42
     */
43
    public function create() : Response
44
    {
45
        if (!$this->request->hasFiles()) {
0 ignored issues
show
Bug introduced by
The property request does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
46
            /**
47
             * @todo handle file hash to avoid uploading same files again
48
             */
49
        }
50
51
        return $this->response($this->processFiles());
0 ignored issues
show
Bug introduced by
It seems like response() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
52
    }
53
54
    /**
55
     * Update an item.
56
     *
57
     * @method PUT
58
     * url /v1/filesystem/{id}
59
     *
60
     * @param mixed $id
61
     *
62
     * @return \Phalcon\Http\Response
63
     * @throws Exception
64
     */
65
    public function edit($id) : Response
66
    {
67
        $file = FileSystem::getById($id);
68
69
        $request = $this->request->getPutData();
70
71
        $systemModule = $request['system_modules_id'] ?? 0;
72
        $entityId = $request['entity_id'] ?? 0;
73
        $fieldName = $request['field_name'] ?? '';
74
75
        //associate
76
        $fileSystemEntities = new FileSystemEntities();
77
        $fileSystemEntities->filesystem_id = $file->getId();
78
        $fileSystemEntities->entity_id = $entityId;
79
        $fileSystemEntities->companies_id = $file->companies_id;
80
        $fileSystemEntities->system_modules_id = $systemModule;
81
        $fileSystemEntities->field_name = $fieldName;
82
        $fileSystemEntities->saveOrFail();
83
84
        $file->updateOrFail($request, $this->updateFields);
0 ignored issues
show
Bug introduced by
The property updateFields does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
85
86
        return $this->response($file);
0 ignored issues
show
Bug introduced by
It seems like response() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
87
    }
88
89
    /**
90
     * Update a filesystem Entity,  field name.
91
     *
92
     * @param int $id
93
     * @return Response
94
     */
95
    public function editEntity(int $id): Response
96
    {
97
        $fileEntity = FileSystemEntities::getById($id);
98
        $request = $this->request->getPutData();
99
100
        $fileEntity->field_name = $request['field_name'];
101
        $fileEntity->updateOrFail();
102
103
        return $this->response($fileEntity);
0 ignored issues
show
Bug introduced by
It seems like response() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
104
    }
105
106
    /**
107
     * Delete a file atribute.
108
     *
109
     * @param $id
110
     * @param string $name
111
     * @return void
0 ignored issues
show
Documentation introduced by
Should the return type not be Response?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
112
     */
113
    public function deleteAttributes($id, string $name): Response
114
    {
115
        $records = FileSystem::findFirstOrFail($id);
116
117
        $recordAttributes = FileSystemSettings::findFirstOrFail([
118
            'conditions' => 'filesystem_id = ?0 and name = ?1',
119
            'bind' => [$records->getId(), $name]
120
        ]);
121
122
        //true true delete
123
        $recordAttributes->delete();
124
125
        return $this->response(['Delete Successfully']);
0 ignored issues
show
Bug introduced by
It seems like response() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
126
    }
127
128
    /**
129
     * Set the validation for the files.
130
     *
131
     * @return Validation
132
     */
133
    protected function validation(): Validation
134
    {
135
        $validator = new Validation();
136
137
        /**
138
         * @todo add validation for other file types, but we need to
139
         * look for a scalable way
140
         */
141
        $uploadConfig = [
142
            'maxSize' => '100M',
143
            'messageSize' => ':field exceeds the max filesize (:max)',
144
            'allowedTypes' => [
145
                'image/jpeg',
146
                'image/png',
147
                'image/webp',
148
                'audio/mpeg',
149
                'audio/mp3',
150
                'audio/mpeg',
151
                'application/pdf',
152
                'audio/mpeg3',
153
                'audio/x-mpeg-3',
154
                'application/x-zip-compressed',
155
                'application/octet-stream',
156
            ],
157
            'messageType' => 'Allowed file types are :types',
158
        ];
159
160
        $validator->add(
161
            'file',
162
            new FileValidator($uploadConfig)
163
        );
164
165
        return $validator;
166
    }
167
168
    /**
169
     * Upload the document and save them to the filesystem.
170
     * @todo add test
171
     *
172
     * @return array
173
     */
174
    protected function processFiles(): array
175
    {
176
        $allFields = $this->request->getPostData();
177
178
        $validator = $this->validation();
179
180
        $files = [];
181
        foreach ($this->request->getUploadedFiles() as $file) {
182
            //validate this current file
183
            $errors = $validator->validate([
184
                'file' => [
185
                    'name' => $file->getName(),
186
                    'type' => $file->getType(),
187
                    'tmp_name' => $file->getTempName(),
188
                    'error' => $file->getError(),
189
                    'size' => $file->getSize(),
190
                ]
191
            ]);
192
193
            /**
194
             * @todo figure out why this failes
195
             */
196
            if (!defined('API_TESTS')) {
197
                if (count($errors)) {
198
                    foreach ($errors as $error) {
199
                        throw new UnprocessableEntityException((string) $error);
200
                    }
201
                }
202
            }
203
204
            $fileSystem = Helper::upload($file);
205
206
            //add settings
207
            foreach ($allFields as $key => $settings) {
208
                $fileSystem->set($key, $settings);
209
            }
210
211
            $files[] = $fileSystem;
212
        }
213
214
        return $files;
215
    }
216
}
217