Issues (46)

src/traits/MediaFilesTrait.php (1 issue)

1
<?php
2
namespace Itstructure\MFUploader\traits;
3
4
use Yii;
5
use yii\web\NotFoundHttpException;
6
use yii\base\{InvalidConfigException, UnknownMethodException};
7
use Itstructure\MFUploader\Module;
8
use Itstructure\MFUploader\models\{Mediafile, OwnerMediafile};
9
use Itstructure\MFUploader\models\upload\BaseUpload;
10
use Itstructure\MFUploader\components\{LocalUploadComponent, S3UploadComponent};
11
use Itstructure\MFUploader\interfaces\{UploadComponentInterface, UploadModelInterface};
12
13
/**
14
 * Trait DeleteFilesTrait
15
 *
16
 * @property UploadComponentInterface[]|LocalUploadComponent[]|S3UploadComponent[] $tmpUploadComponents
17
 * Upload components to delete files according with their different types.
18
 *
19
 * @package Itstructure\MFUploader\traits
20
 *
21
 * @author Andrey Girnik <[email protected]>
22
 */
23
trait MediaFilesTrait
24
{
25
    /**
26
     * Upload components to delete files according with their different types.
27
     *
28
     * @var UploadComponentInterface[]|LocalUploadComponent[]|S3UploadComponent[]
29
     */
30
    protected $tmpUploadComponents = [];
31
32
    /**
33
     * Delete mediafiles from owner.
34
     *
35
     * @param string $owner
36
     * @param int $ownerId
37
     * @param Module $module
38
     * @param bool $protectMultiplied
39
     *
40
     * @return void
41
     */
42
    protected function deleteMediafiles(string $owner, int $ownerId, Module $module, bool $protectMultiplied = true): void
43
    {
44
        $mediafileIds = array_map(function ($data) {
45
            return $data->id;
46
47
        }, OwnerMediafile::getMediaFilesQuery([
48
            'owner' => $owner,
49
            'ownerId' => $ownerId
50
        ])
51
            ->select('id')
52
            ->all()
53
        );
54
55
        if ($protectMultiplied) {
56
            $multipliedMediafileIds = array_map(function ($data) {
57
                return $data->mediafileId;
58
59
            }, OwnerMediafile::filterMultipliedEntityIds($owner, $ownerId, $mediafileIds));
60
61
            $mediafileIds = array_filter($mediafileIds, function ($item) use ($multipliedMediafileIds) {
62
                return !in_array($item, $multipliedMediafileIds);
63
            });
64
65
            OwnerMediafile::deleteAll([
66
                'owner' => $owner,
67
                'ownerId' => $ownerId,
68
                'mediafileId' => $multipliedMediafileIds
69
            ]);
70
        }
71
72
        $this->deleteMediafileEntry($mediafileIds, $module);
73
    }
74
75
    /**
76
     * Find the media model entry.
77
     *
78
     * @param int $id
79
     *
80
     * @throws UnknownMethodException
81
     * @throws NotFoundHttpException
82
     *
83
     * @return Mediafile
84
     */
85
    protected function findMediafileModel(int $id): Mediafile
86
    {
87
        $modelObject = new Mediafile();
88
89
        if (!method_exists($modelObject, 'findOne')) {
90
            $class = (new\ReflectionClass($modelObject));
91
            throw new UnknownMethodException('Method findOne does not exists in ' . $class->getNamespaceName() . '\\' .
92
                $class->getShortName().' class.');
93
        }
94
95
        $result = call_user_func([
96
            $modelObject,
97
            'findOne',
98
        ], $id);
99
100
        if ($result !== null) {
101
            return $result;
102
        }
103
104
        throw new NotFoundHttpException('The requested page does not exist.');
105
    }
106
107
    /**
108
     * Delete mediafile record with files.
109
     *
110
     * @param array|int|string $id
111
     * @param Module $module
112
     *
113
     * @throws InvalidConfigException
114
     *
115
     * @return bool|int
116
     */
117
    protected function deleteMediafileEntry($id, Module $module)
118
    {
119
        if (is_array($id)) {
120
            $i = 0;
121
            foreach ($id as $item) {
122
                if (!$this->deleteMediafileEntry((int)$item, $module)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->deleteMediafileEntry((int)$item, $module) of type false|integer is loosely compared to false; this is ambiguous if the integer can be 0. You might want to explicitly use === false instead.

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

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
123
                    return false;
124
                }
125
                $i += 1;
126
            }
127
            return $i;
128
129
        } else {
130
            $mediafileModel = $this->findMediafileModel((int)$id);
131
132
            switch ($mediafileModel->storage) {
133
                case Module::STORAGE_TYPE_LOCAL:
134
                    $this->setComponentIfNotIsset($mediafileModel->storage, 'local-upload-component', $module);
135
                    break;
136
137
                case Module::STORAGE_TYPE_S3:
138
                    $this->setComponentIfNotIsset($mediafileModel->storage, 's3-upload-component', $module);
139
                    break;
140
141
                default:
142
                    throw new InvalidConfigException('Unknown type of the file storage');
143
            }
144
145
            /** @var UploadModelInterface|BaseUpload $deleteModel */
146
            $deleteModel = $this->tmpUploadComponents[$mediafileModel->storage]->setModelForDelete($mediafileModel);
147
148
            if ($deleteModel->delete() === 0) {
149
                return false;
150
            }
151
152
            return 1;
153
        }
154
    }
155
156
    /**
157
     * Set tmp upload component if not isset.
158
     *
159
     * @param string $storage
160
     * @param string $componentName
161
     * @param Module $module
162
     *
163
     * @return void
164
     */
165
    private function setComponentIfNotIsset(string $storage, string $componentName, Module $module): void
166
    {
167
        if (!isset($this->tmpUploadComponents[$storage])) {
168
            $this->tmpUploadComponents[$storage] = $module->get($componentName);
169
        }
170
    }
171
}
172