Failed Conditions
Pull Request — master (#318)
by Maximo
02:52
created

FileSystemModelTrait::deleteFiles()   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 0
dl 0
loc 12
ccs 0
cts 8
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 Canvas\Models\SystemModules;
8
use Canvas\Models\FileSystem;
9
use RuntimeException;
10
use Canvas\Models\FileSystemEntities;
11
use Canvas\Dto\Files;
12
use Canvas\Mapper\FileMapper;
13
use Phalcon\Mvc\Model\ResultsetInterface;
14
15
/**
16
 * Trait ResponseTrait.
17
 *
18
 * @package Canvas\Traits
19
 *
20
 * @property Users $user
21
 * @property AppsPlans $appPlan
22
 * @property CompanyBranches $branches
23
 * @property Companies $company
24
 * @property UserCompanyApps $app
25
 * @property \Phalcon\Di $di
26
 *
27
 */
28
trait FileSystemModelTrait
29
{
30
    public $uploadedFiles = [];
31
32
    /**
33
     * Associated the list of uploaded files to this entity.
34
     *
35
     * call on the after saves
36
     *
37
     * @return void
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean?

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...
38
     */
39
    protected function associateFileSystem(): bool
0 ignored issues
show
Coding Style introduced by
function associateFileSystem() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
40
    {
41
        if (!empty($this->uploadedFiles) && is_array($this->uploadedFiles)) {
42
            foreach ($this->uploadedFiles as $file) {
43
                if (!isset($file['filesystem_id'])) {
44
                    continue;
45
                }
46
47
                if ($fileSystem = FileSystem::getById($file['filesystem_id'])) {
48
                    $this->attach([[
49
                        'id' => $file['id'] ?: 0,
50
                        'file' => $fileSystem,
51
                        'field_name' => $file['field_name'] ?? ''
52
                    ]]);
53
                }
54
            }
55
        }
56
57
        return true;
58
    }
59
60
    /**
61
     * Over write, because of the phalcon events.
62
     *
63
     * @param array data
64
     * @param array whiteList
65
     * @return boolean
66
     */
67
    public function update($data = null, $whiteList = null): bool
0 ignored issues
show
Coding Style introduced by
function update() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
68
    {
69
        //associate uploaded files
70
        if (isset($data['files'])) {
71
            if (!empty($data['files'])) {
72
                /**
73
                 * @todo for now lets delete them all and updated them
74
                 * look for a better solution later, this can since we are not using transactions
75
                 */
76
                $this->deleteFiles();
77
78
                $this->uploadedFiles = $data['files'];
79
            } else {
80
                $this->deleteFiles();
81
            }
82
        }
83
84
        return parent::update($data, $whiteList);
85
    }
86
87
    /**
88
     * Inserts or updates a model instance. Returning true on success or false otherwise.
89
     *
90
     *<code>
91
     * // Creating a new robot
92
     * $robot = new Robots();
93
     *
94
     * $robot->type = "mechanical";
95
     * $robot->name = "Astro Boy";
96
     * $robot->year = 1952;
97
     *
98
     * $robot->save();
99
     *
100
     * // Updating a robot name
101
     * $robot = Robots::findFirst("id = 100");
102
     *
103
     * $robot->name = "Biomass";
104
     *
105
     * $robot->save();
106
     *</code>
107
     *
108
     * @param array data
109
     * @param array whiteList
110
     * @return boolean
111
     */
112
    public function save($data = null, $whiteList = null): bool
0 ignored issues
show
Coding Style introduced by
function save() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
113
    {
114
        //associate uploaded files
115
        if (isset($data['files'])) {
116
            if (!empty($data['files'])) {
117
                $this->uploadedFiles = $data['files'];
118
            }
119
        }
120
121
        return parent::save($data, $whiteList);
122
    }
123
124
    /**
125
     * Delete all the files from a module.
126
     *
127
     * @return bool
128
     */
129
    public function deleteFiles(): bool
0 ignored issues
show
Coding Style introduced by
function deleteFiles() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
130
    {
131
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
0 ignored issues
show
Deprecated Code introduced by
The method Canvas\Models\SystemModu...stemModuleByModelName() has been deprecated with message: v2

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
132
133
        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?

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...
134
            $files->update([], function ($file) {
135
                $file->softDelete();
136
            });
137
        }
138
139
        return true;
140
    }
141
142
    /**
143
     * Given the ID delete the file from this entity.
144
     *
145
     * @param integer $id
146
     * @return bool
147
     */
148
    public function deleteFile(int $id)
0 ignored issues
show
Coding Style introduced by
function deleteFile() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
149
    {
150
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
0 ignored issues
show
Deprecated Code introduced by
The method Canvas\Models\SystemModu...stemModuleByModelName() has been deprecated with message: v2

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
151
152
        $file = FileSystemEntities::findFirstOrFail([
153
            'contidions' => 'id = ?0 AND entity_id = ?1 AND system_modules_id = ?2 AND is_deleted = ?3',
154
            'bind' => [$id, $this->getId(), $systemModule->getId(), 0]
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?

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...
155
        ]);
156
157
        if ($file) {
158
            $file->softDelete();
159
        }
160
161
        return false;
162
    }
163
164
    /**
165
     * Given the array of files we will attch this files to the files.
166
     * [
167
     *  'file' => $file,
168
     *  'file_name' => 'dfadfa'
169
     * ];.
170
     *
171
     * @param array $files
172
     * @return void
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean?

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...
173
     */
174
    public function attach(array $files): bool
0 ignored issues
show
Coding Style introduced by
function attach() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
175
    {
176
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
0 ignored issues
show
Deprecated Code introduced by
The method Canvas\Models\SystemModu...stemModuleByModelName() has been deprecated with message: v2

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
177
178
        foreach ($files as $file) {
179
            //im looking for the file inside an array
180
            if (!isset($file['file'])) {
181
                continue;
182
            }
183
184
            if (!$file['file'] instanceof FileSystem) {
185
                throw new RuntimeException('Cant attach a none Filesytem to this entity');
186
            }
187
188
            $fileSystemEntities = null;
189
            //check if we are updating the attachment
190
            if ($id = (int) $file['id']) {
191
                $fileSystemEntities = FileSystemEntities::getByIdWithSystemModule($id, $systemModule);
192
            }
193
194
            //new attachment
195
            if (!is_object($fileSystemEntities)) {
196
                $fileSystemEntities = new FileSystemEntities();
197
                $fileSystemEntities->system_modules_id = $systemModule->getId();
198
                $fileSystemEntities->companies_id = $file['file']->companies_id;
199
                $fileSystemEntities->entity_id = $this->getId();
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?

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...
200
                $fileSystemEntities->created_at = $file['file']->created_at;
201
            }
202
203
            $fileSystemEntities->filesystem_id = $file['file']->getId();
204
            $fileSystemEntities->field_name = $file['field_name'] ?? null;
205
            $fileSystemEntities->is_deleted = 0;
206
            $fileSystemEntities->saveOrFail();
207
208
            if (!is_null($this->filesNewAttachedPath())) {
209
                $file['file']->move($this->filesNewAttachedPath());
210
            }
211
        }
212
213
        return true;
214
    }
215
216
    /**
217
     * Get all the files attach for the given module.
218
     *
219
     * @param string $fileType filter the files by their type
0 ignored issues
show
Documentation introduced by
Should the type for parameter $fileType not be null|string?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
220
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be ResultsetInterface?

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...
221
     */
222
    public function getAttachments(string $fileType = null) : ResultsetInterface
223
    {
224
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
0 ignored issues
show
Deprecated Code introduced by
The method Canvas\Models\SystemModu...stemModuleByModelName() has been deprecated with message: v2

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
225
        $appPublicImages = (bool) $this->di->getApp()->get('public_images');
226
227
        $bindParams = [
228
            $systemModule->getId(),
229
            $this->getId(),
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?

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...
230
            0,
231
        ];
232
233
        //do we allow images by entity to be public to anybody accessing it directly by the entity?
234
        if ($appPublicImages) {
235
            $fileTypeSql = !is_null($fileType) ? 'AND f.file_type = ?3' : null;
236
237
            $condition = 'system_modules_id = ?0 AND entity_id = ?1 AND is_deleted = ?2
238
            AND filesystem_id IN (SELECT f.id from \Canvas\Models\FileSystem f WHERE
239
                f.is_deleted = ?2 ' . $fileTypeSql . '
240
            )';
241
        } else {
242
            $fileTypeSql = !is_null($fileType) ? 'AND f.file_type = ?4' : null;
243
            $bindParams[] = $this->di->getUserData()->currentCompanyId();
244
245
            $condition = 'system_modules_id = ?0 AND entity_id = ?1 AND is_deleted = ?2 and companies_id = ?3
246
            AND filesystem_id IN (SELECT f.id from \Canvas\Models\FileSystem f WHERE
247
                f.is_deleted = ?2 AND f.companies_id = ?3 ' . $fileTypeSql . '
248
            )';
249
        }
250
251
        /**
252
          * We can also filter the attachements by its file type.
253
          */
254
        if ($fileTypeSql) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $fileTypeSql of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
255
            $bindParams[] = $fileType;
256
        }
257
258
        return FileSystemEntities::find([
259
            'conditions' => $condition,
260
            'bind' => $bindParams
261
        ]);
262
    }
263
264
    /**
265
     * Overwrite the relationship of the filesystem to return the attachment structure
266
     * to the given user.
267
     *
268
     * @deprecated version 0.2
269
     * @return array
270
     */
271
    public function getFilesystem(): array
272
    {
273
        return $this->getFiles();
274
    }
275
276
    /**
277
     * Overwrite the relationship of the filesystem to return the attachment structure
278
     * to the given user.
279
     *
280
     * @return array
281
     */
282
    public function getFiles(string $fileType = null): array
283
    {
284
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
0 ignored issues
show
Deprecated Code introduced by
The method Canvas\Models\SystemModu...stemModuleByModelName() has been deprecated with message: v2

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
285
286
        $attachments = $this->getAttachments($fileType);
287
288
        $fileMapper = new FileMapper($this->getId(), $systemModule->getId());
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?

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...
289
290
        //add a mapper
291
        $this->di->getDtoConfig()
292
            ->registerMapping(FileSystemEntities::class, Files::class)
293
            ->useCustomMapper($fileMapper);
294
295
        return $this->di->getMapper()->mapMultiple($attachments, Files::class);
296
    }
297
298
    /**
299
     * Get a file by its fieldname.
300
     *
301
     * @todo this will be a performance issue in the futur look for better ways to handle this
302
     * when a company has over 1k images
303
     *
304
     * @deprecated version 0.2
305
     * @param string $name
0 ignored issues
show
Bug introduced by
There is no parameter named $name. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
306
     * @return void
307
     */
308
    public function getAttachmentByName(string $fieldName)
309
    {
310
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
0 ignored issues
show
Deprecated Code introduced by
The method Canvas\Models\SystemModu...stemModuleByModelName() has been deprecated with message: v2

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
311
        $appPublicImages = (bool) $this->di->getApp()->get('public_images');
312
313
        $bind = [
314
            $systemModule->getId(),
315
            $this->getId(),
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?

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...
316
            0,
317
            $fieldName,
318
        ];
319
320
        //do we allow images by entity to be public to anybody accessing it directly by the entity?
321
        if ($appPublicImages) {
322
            $condition = 'system_modules_id = ?0 AND entity_id = ?1 AND is_deleted = ?2 and field_name = ?3 
323
            AND filesystem_id IN (SELECT f.id from \Canvas\Models\FileSystem f WHERE
324
                f.is_deleted = ?2
325
            )';
326
        } else {
327
            $bind[] = $this->di->getUserData()->currentCompanyId();
328
            $condition = 'system_modules_id = ?0 AND entity_id = ?1 AND is_deleted = ?2 and field_name = ?3 and companies_id = ?4
329
            AND filesystem_id IN (SELECT f.id from \Canvas\Models\FileSystem f WHERE
330
                f.is_deleted = ?2 AND f.companies_id = ?4
331
            )';
332
        }
333
334
        return FileSystemEntities::findFirst([
335
            'conditions' => $condition,
336
            'bind' => $bind
337
        ]);
338
    }
339
340
    /**
341
     * Undocumented function.
342
     *
343
     * @param string $fieldName
344
     * @return string|null
345
     */
346
    public function getFileByName(string $fieldName): ?object
347
    {
348
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
0 ignored issues
show
Deprecated Code introduced by
The method Canvas\Models\SystemModu...stemModuleByModelName() has been deprecated with message: v2

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
349
350
        $fileEntity = $this->getAttachmentByName($fieldName);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $fileEntity is correct as $this->getAttachmentByName($fieldName) (which targets Canvas\Traits\FileSystem...::getAttachmentByName()) 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...
Deprecated Code introduced by
The method Canvas\Traits\FileSystem...::getAttachmentByName() has been deprecated with message: version 0.2

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
351
352
        if ($fileEntity) {
353
            $fileMapper = new FileMapper($this->getId(), $systemModule->getId());
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?

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...
354
355
            //add a mapper
356
            $this->di->getDtoConfig()
357
                ->registerMapping(FileSystemEntities::class, Files::class)
358
                ->useCustomMapper($fileMapper);
359
360
            /**
361
             * @todo create a mapper for entity so we dont have to look for the relationship?
362
             */
363
            return $this->di->getMapper()->map($fileEntity, Files::class);
364
        }
365
366
        return null;
367
    }
368
369
    /**
370
     * Given this entity define a new path.
371
     *
372
     * @param string $path
0 ignored issues
show
Bug introduced by
There is no parameter named $path. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
373
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

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...
374
     */
375
    protected function filesNewAttachedPath(): ?string
376
    {
377
        return null;
378
    }
379
}
380