Completed
Push — master ( 531a23...3492bb )
by Vladimir
27:36
created

BannerService::save()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 1
1
<?php
2
/**
3
 * @link https://github.com/yiimaker/yii2-banner
4
 * @copyright Copyright (c) 2017 Yii Maker
5
 * @license BSD 3-Clause License
6
 */
7
8
namespace ymaker\banner\backend\services;
9
10
use Yii;
11
use yii\base\Object;
12
use yii\data\ActiveDataProvider;
13
use yii\db\Connection;
14
use yii\di\Instance;
15
use yii\web\NotFoundHttpException;
16
use yii\web\UploadedFile;
17
use ymaker\banner\backend\exceptions\FileUploadException;
18
use ymaker\banner\backend\models\entities\Banner;
19
use ymaker\banner\backend\models\entities\BannerTranslation;
20
use ymaker\banner\common\components\FileManager;
21
22
/**
23
 * Service for banner.
24
 *
25
 * @author Vladimir Kuprienko <[email protected]>
26
 * @since 1.0
27
 */
28
class BannerService extends Object implements BannerServiceInterface
29
{
30
    /**
31
     * @var string|array|Connection
32
     */
33
    private $_db = 'db';
34
    /**
35
     * @var FileManager
36
     */
37
    private $_fileManager;
38
    /**
39
     * @var Banner
40
     */
41
    private $_model;
42
43
44
    /**
45
     * @inheritdoc
46
     * @param FileManager $fileManager
47
     */
48
    public function __construct(FileManager $fileManager, $config = [])
49
    {
50
        $this->_fileManager = $fileManager;
51
        parent::__construct($config);
52
    }
53
54
    /**
55
     * @param string|array|Connection $db
56
     */
57
    public function setDb($db)
58
    {
59
        $this->_db = $db;
60
    }
61
62
    /**
63
     * @inheritdoc
64
     */
65
    public function init()
66
    {
67
        $this->_db = Instance::ensure($this->_db, Connection::class);
68
    }
69
70
    /**
71
     * @return \yii\data\ActiveDataProvider
72
     */
73
    public function getDataProvider()
74
    {
75
        return new ActiveDataProvider([
76
            'db' => $this->_db,
77
            'query' => Banner::find()->with('translations'),
78
        ]);
79
    }
80
81
    /**
82
     * @param int $id
83
     * @return Banner
84
     * @throws NotFoundHttpException
85
     */
86
    private function findModel($id)
87
    {
88
        if ($model = Banner::findOne($id)) {
89
            return $model;
90
        }
91
        throw new NotFoundHttpException();
92
    }
93
94
    /**
95
     * Returns primary model object.
96
     *
97
     * @param null|int $id
98
     * @return Banner
99
     * @throws NotFoundHttpException
100
     */
101
    public function getModel($id = null)
102
    {
103
        if ($id === null) {
104
            $model = new Banner();
105
            $model->loadDefaultValues();
106
            $this->_model = $model;
107
        } else {
108
            $this->_model = $this->findModel($id);
109
        }
110
111
        return $this->_model;
112
    }
113
114
    /**
115
     * Save uploaded file to file system.
116
     *
117
     * @param BannerTranslation $model
118
     * @return string
119
     * @throws FileUploadException
120
     */
121
    private function saveUploadedFile($model)
122
    {
123
        $uploadedFile = UploadedFile::getInstance($model, 'imageFile');
124
        if ($uploadedFile === null) {
125
            return $model->file_name;
126
        }
127
128
        $fileName = $this->_fileManager->generateFileName($uploadedFile->extension);
129
        if ($uploadedFile->saveAs($this->_fileManager->getImageSrc($fileName))) {
130
            if (!$model->getIsNewRecord()) {
131
                $this->_fileManager->deleteFile($model->file_name);
132
            }
133
            return $fileName;
134
        }
135
136
        throw new FileUploadException('Error code #' . $uploadedFile->error);
137
    }
138
139
    /**
140
     * Save banner to database.
141
     *
142
     * @param array $data
143
     * @throws FileUploadException
144
     * @throws \DomainException
145
     * @throws \RuntimeException
146
     */
147
    protected function saveInternal(array $data)
148
    {
149
        if (!$this->_model->load($data)) {
150
            throw new \DomainException('Cannot load data to primary model');
151
        }
152
153
        foreach ($data[BannerTranslation::internalFormName()] as $language => $dataSet) {
154
            $model = $this->_model->getTranslation($language);
155
            $model->file_name = $this->saveUploadedFile($model);
156
            foreach ($dataSet as $attribute => $translation) {
157
                $model->$attribute = $translation;
158
            }
159
        }
160
161
        if (!$this->_model->save()) {
162
            throw new \RuntimeException();
163
        }
164
    }
165
166
    /**
167
     * Save banner and log exceptions.
168
     *
169
     * @param array $data
170
     * @return bool
171
     */
172
    public function save(array $data)
173
    {
174
        try {
175
            $this->saveInternal($data);
176
            return true;
177
        } catch (\Exception $ex) {
178
            Yii::$app->getErrorHandler()->logException($ex);
179
        }
180
181
        return false;
182
    }
183
184
    /**
185
     * Removes banner.
186
     *
187
     * @param int $id
188
     * @return bool
189
     * @throws NotFoundHttpException
190
     */
191
    public function delete($id)
192
    {
193
        try {
194
            $model = $this->findModel($id);
195
            foreach ($model->translations as $translation) {
196
                if (!$this->_fileManager->deleteFile($translation->file_name)) {
197
                    Yii::trace('Cannot delete "' . $translation->file_name . '" file', 'yii2-banner');
198
                }
199
            }
200
            return (bool)$model->delete();
201
        } catch (\Exception $ex) {
202
            Yii::$app->getErrorHandler()->logException($ex);
203
        }
204
205
        return false;
206
    }
207
}
208