Test Failed
Push — master ( 004faa...c8ffdf )
by Maximo
11:48 queued 05:52
created

FileSystemModelTrait::getFileByName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 26
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 10
nc 2
nop 1
dl 0
loc 26
ccs 0
cts 17
cp 0
crap 6
rs 9.9332
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Canvas\Traits;
6
7
use Canvas\Models\SystemModules;
8
use Canvas\Models\FileSystem;
9
use RuntimeException;
10
use Phalcon\Mvc\Model\Resultset\Simple;
0 ignored issues
show
Bug introduced by
The type Phalcon\Mvc\Model\Resultset\Simple was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Canvas\Models\FileSystemEntities;
12
use Canvas\Dto\Files;
13
use Canvas\Mapper\FileMapper;
14
use Phalcon\Di;
15
16
/**
17
 * Trait ResponseTrait.
18
 *
19
 * @package Canvas\Traits
20
 *
21
 * @property Users $user
22
 * @property AppsPlans $appPlan
23
 * @property CompanyBranches $branches
24
 * @property Companies $company
25
 * @property UserCompanyApps $app
26
 * @property \Phalcon\Di $di
27
 *
28
 */
29
trait FileSystemModelTrait
30
{
31
    public $uploadedFiles = [];
32
33
    /**
34
     * Associated the list of uploaded files to this entity.
35
     *
36
     * call on the after saves
37
     *
38
     * @return void
39
     */
40
    protected function associateFileSystem(): bool
41
    {
42
        if (!empty($this->uploadedFiles) && is_array($this->uploadedFiles)) {
43
            foreach ($this->uploadedFiles as $file) {
44
                if (!isset($file['filesystem_id'])) {
45
                    continue;
46
                }
47
48
                if ($fileSystem = FileSystem::getById($file['filesystem_id'])) {
49
                    $this->attach([[
50
                        'id' => $file['id'] ?: 0,
51
                        'file' => $fileSystem,
52
                        'field_name' => $file['field_name'] ?? ''
53
                    ]]);
54
                }
55
            }
56
        }
57
58
        return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the documented return type void.
Loading history...
59
    }
60
61
    /**
62
     * Over write, because of the phalcon events.
63
     *
64
     * @param array data
65
     * @param array whiteList
0 ignored issues
show
Bug introduced by
The type Canvas\Traits\whiteList was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
66
     * @return boolean
67
     */
68
    public function update($data = null, $whiteList = null): bool
69
    {
70
        //associate uploaded files
71
        if (isset($data['files'])) {
72
            if (!empty($data['files'])) {
73
                $this->uploadedFiles = $data['files'];
74
            } else {
75
                $this->deleteFiles();
76
            }
77
        }
78
79
        return parent::update($data, $whiteList);
80
    }
81
82
    /**
83
     * Inserts or updates a model instance. Returning true on success or false otherwise.
84
     *
85
     *<code>
86
     * // Creating a new robot
87
     * $robot = new Robots();
88
     *
89
     * $robot->type = "mechanical";
90
     * $robot->name = "Astro Boy";
91
     * $robot->year = 1952;
92
     *
93
     * $robot->save();
94
     *
95
     * // Updating a robot name
96
     * $robot = Robots::findFirst("id = 100");
97
     *
98
     * $robot->name = "Biomass";
99
     *
100
     * $robot->save();
101
     *</code>
102
     *
103
     * @param array data
104
     * @param array whiteList
105
     * @return boolean
106
     */
107
    public function save($data = null, $whiteList = null): bool
108
    {
109
        //associate uploaded files
110
        if (isset($data['files'])) {
111
            if (!empty($data['files'])) {
112
                $this->uploadedFiles = $data['files'];
113
            } else {
114
                $this->deleteFiles();
115
            }
116
        }
117
118
        return parent::save($data, $whiteList);
119
    }
120
121
    /**
122
     * Delete all the files from a module.
123
     *
124
     * @return bool
125
     */
126
    public function deleteFiles(): bool
127
    {
128
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
129
130
        if ($files = FileSystemEntities::getAllByEntityId($this->getId(), $systemModule)) {
0 ignored issues
show
Bug introduced by
It seems like getId() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

130
        if ($files = FileSystemEntities::getAllByEntityId($this->/** @scrutinizer ignore-call */ getId(), $systemModule)) {
Loading history...
Unused Code introduced by
The call to Canvas\Models\FileSystem...ies::getAllByEntityId() has too many arguments starting with $systemModule. ( Ignorable by Annotation )

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

130
        if ($files = FileSystemEntities::/** @scrutinizer ignore-call */ getAllByEntityId($this->getId(), $systemModule)) {

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
131
            foreach ($files as $file) {
132
                $file->softDelete();
133
            }
134
        }
135
136
        return true;
137
    }
138
139
    /**
140
     * Given the ID delete the file from this entity.
141
     *
142
     * @param integer $id
143
     * @return bool
144
     */
145
    public function deleteFile(int $id)
146
    {
147
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
148
149
        $file = FileSystemEntities::findFirstOrFail([
150
            'contidions' => 'id = ?0 AND entity_id = ?1 AND system_modules_id = ?2 AND is_deleted = ?3',
151
            'bind' => [$id, $this->getId(), $systemModule->getId(), 0]
152
        ]);
153
154
        return $file->softDelete();
0 ignored issues
show
Bug introduced by
Are you sure the usage of $file->softDelete() targeting Baka\Database\Model::softDelete() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug Best Practice introduced by
The expression return $file->softDelete() returns the type void which is incompatible with the documented return type boolean.
Loading history...
155
    }
156
157
    /**
158
     * Given the array of files we will attch this files to the files.
159
     * [
160
     *  'file' => $file,
161
     *  'file_name' => 'dfadfa'
162
     * ];.
163
     *
164
     * @param array $files
165
     * @return void
166
     */
167
    public function attach(array $files): bool
168
    {
169
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
170
171
        foreach ($files as $file) {
172
            //im looking for the file inside an array
173
            if (!array_key_exists('file', $file)) {
174
                continue;
175
            }
176
177
            if (!$file['file'] instanceof FileSystem) {
178
                throw new RuntimeException('Cant attach a one Filesytem to this entity');
179
            }
180
181
            //check if we are updating the attachment
182
            if (array_key_exists('id', $file) && (int) $file['id']) {
183
                $fileSystemEntities = FileSystemEntities::getByIdWithSystemModule($file['id'], $systemModule);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $fileSystemEntities is correct as Canvas\Models\FileSystem...e['id'], $systemModule) targeting Canvas\Models\FileSystem...tByIdWithSystemModule() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
184
            }
185
186
            //new attachment
187
            if (!is_object($fileSystemEntities)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $fileSystemEntities does not seem to be defined for all execution paths leading up to this point.
Loading history...
188
                $fileSystemEntities = new FileSystemEntities();
189
                $fileSystemEntities->system_modules_id = $systemModule->getId();
190
                $fileSystemEntities->companies_id = $file['file']->companies_id;
191
                $fileSystemEntities->entity_id = $this->getId();
192
                $fileSystemEntities->created_at = $file['file']->created_at;
193
            }
194
195
            $fileSystemEntities->filesystem_id = $file['file']->getId();
196
            $fileSystemEntities->field_name = $file['field_name'] ?? null;
197
            $fileSystemEntities->is_deleted = 0 ;
198
            $fileSystemEntities->saveOrFail();
199
200
            if (!is_null($this->filesNewAttachedPath())) {
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->filesNewAttachedPath() targeting Canvas\Traits\FileSystem...:filesNewAttachedPath() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
201
                $file['file']->move($this->filesNewAttachedPath());
202
            }
203
        }
204
205
        return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the documented return type void.
Loading history...
206
    }
207
208
    /**
209
     * Get all the files attach for the given module.
210
     *
211
     * @param string $fileType filter the files by their type
212
     * @return array
213
     */
214
    public function getAttachments(string $fileType = null) : array
215
    {
216
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
217
        $bindParams = [
218
            0,
219
            $systemModule->getId(),
220
            $this->getId()
221
        ];
222
223
        /**
224
         * We can also filter the attachements by its file type.
225
         */
226
        $fileTypeSql = !is_null($fileType) ? 'AND file_type = ?3' : null;
227
        if ($fileTypeSql) {
228
            $bindParams[] = $fileType;
229
        }
230
231
        $attachments = FileSystem::find([
232
            'conditions' => '
233
                is_deleted = ?0 AND id in 
234
                    (SELECT 
235
                        filesystem_id from \Canvas\Models\FileSystemEntities e
236
                        WHERE e.system_modules_id = ?1 AND e.entity_id = ?2 AND e.is_deleted = ?0
237
                    )' . $fileTypeSql,
238
            'bind' => $bindParams
239
        ]);
240
241
        $fileMapper = new FileMapper($this->getId(), $systemModule->getId());
242
243
        //add a mapper
244
        $this->di->getDtoConfig()->registerMapping(FileSystem::class, Files::class)
245
            ->useCustomMapper($fileMapper);
246
247
        return $this->di->getMapper()->mapMultiple($attachments, Files::class);
248
    }
249
250
    /**
251
     * Overwrite the relationship of the filesystem to return the attachment structure
252
     * to the given user.
253
     *
254
     * @deprecated version 0.2
255
     * @return array
256
     */
257
    public function getFilesystem(): array
258
    {
259
        return $this->getAttachments();
260
    }
261
262
    /**
263
     * Overwrite the relationship of the filesystem to return the attachment structure
264
     * to the given user.
265
     *
266
     * @return array
267
     */
268
    public function getFiles(string $fileType = null): array
269
    {
270
        return $this->getAttachments($fileType);
271
    }
272
273
    /**
274
     * Get a file by its fieldname.
275
     *
276
     * @todo this will be a performance issue in the futur look for better ways to handle this
277
     * when a company has over 1k images
278
     *
279
     * @deprecated version 0.2
280
     * @param string $name
281
     * @return void
282
     */
283
    public function getAttachementByName(string $fieldName): ?object
284
    {
285
        return $this->getFileByName($fieldName);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getFileByName($fieldName) also could return the type object which is incompatible with the documented return type void.
Loading history...
286
    }
287
288
    /**
289
     * Undocumented function.
290
     *
291
     * @param string $fieldName
292
     * @return string|null
293
     */
294
    public function getFileByName(string $fieldName): ?object
295
    {
296
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
297
298
        $fileEntity = FileSystemEntities::findFirst([
299
            'conditions' => 'system_modules_id = ?0 AND entity_id = ?1 AND is_deleted = ?2 and field_name = ?3 and companies_id = ?4
300
                            AND filesystem_id IN (SELECT f.id from \Canvas\Models\FileSystem f WHERE
301
                                f.is_deleted = ?2 AND f.companies_id = ?4
302
                            )',
303
            'bind' => [$systemModule->getId(), $this->getId(), 0, $fieldName]
304
        ]);
305
306
        if ($fileEntity) {
307
            $fileMapper = new FileMapper($this->getId(), $systemModule->getId());
308
309
            //add a mapper
310
            $this->di->getDtoConfig()->registerMapping(FileSystem::class, Files::class)
311
                ->useCustomMapper($fileMapper);
312
313
            /**
314
             * @todo create a mapper for entity so we dont have to look for the relationship?
315
             */
316
            return $this->di->getMapper()->map($fileEntity->file, Files::class);
317
        }
318
319
        return null;
320
    }
321
322
    /**
323
     * Given this entity define a new path.
324
     *
325
     * @param string $path
326
     * @return string
327
     */
328
    protected function filesNewAttachedPath(): ?string
329
    {
330
        return null;
331
    }
332
}
333