Completed
Push — master ( d8b05f...8a2992 )
by Jeff
02:59
created

ContentController::actionPreview()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
3
namespace app\controllers;
4
5
use Yii;
6
use app\models\Content;
7
use app\models\ContentType;
8
use app\models\Flow;
9
use yii\helpers\Url;
10
use yii\data\ActiveDataProvider;
11
use yii\web\UploadedFile;
12
use yii\web\NotFoundHttpException;
13
use yii\filters\AccessControl;
14
use yii\filters\VerbFilter;
15
16
/**
17
 * ContentController implements the CRUD actions for Content model.
18
 */
19
class ContentController extends BaseController
20
{
21
    /**
22
     * {@inheritdoc}
23
     */
24
    public function behaviors()
25
    {
26
        return [
27
            'verbs' => [
28
                'class' => VerbFilter::className(),
29
                'actions' => [
30
                    'delete' => ['POST'],
31
                ],
32
            ],
33
            'access' => [
34
                'class' => AccessControl::className(),
35
                'only' => ['index', 'view', 'create', 'generate', 'upload', 'sideload', 'update', 'delete', 'toggle'],
36
                'rules' => [
37
                    ['allow' => true, 'actions' => ['create'], 'roles' => ['setContent']],
38
                    ['allow' => true, 'actions' => ['index', 'view', 'generate', 'upload', 'sideload', 'update', 'delete', 'toggle'], 'roles' => ['@']],
39
                ],
40
            ],
41
        ];
42
    }
43
44
    /**
45
     * Lists all Content models.
46
     *
47
     * @return string
48
     */
49
    public function actionIndex()
50
    {
51
        $query = Content::availableQuery(Yii::$app->user);
52
        if ($query === null) {
53
            throw new \yii\web\ForbiddenHttpException(Yii::t('app', 'You do not have enough rights to view this content.'));
54
        }
55
56
        $dataProvider = new ActiveDataProvider([
57
            'query' => $query,
58
        ]);
59
60
        $dataProvider->sort->attributes['type.name'] = [
61
            'asc' => [ContentType::tableName().'.id' => SORT_ASC],
62
            'desc' => [ContentType::tableName().'.id' => SORT_DESC],
63
        ];
64
65
        return $this->render('index', [
66
            'dataProvider' => $dataProvider,
67
        ]);
68
    }
69
70
    /**
71
     * Displays a single Content model.
72
     *
73
     * @param int $id
74
     *
75
     * @return string
76
     */
77
    public function actionView($id)
78
    {
79
        $model = $this->findViewableModel($id, Yii::$app->user);
80
81
        return $this->render('view', [
82
            'model' => $model,
83
        ]);
84
    }
85
86
    /**
87
     * Creates a new Content model.
88
     * If creation is successful, the browser will be redirected to the 'view' page.
89
     *
90
     * @param int $flowId
91
     *
92
     * @return \yii\web\Response|string redirect or render
93
     */
94
    public function actionCreate($flowId)
95
    {
96
        $model = new Content();
97
        $flow = Flow::findOne($flowId);
98
        if ($flow === null) {
99
            throw new NotFoundHttpException(Yii::t('app', 'The requested flow does not exist.'));
100
        }
101
        $model->flow_id = $flow->id;
102
103 View Code Duplication
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
104
            return $this->redirect(['view', 'id' => $model->id]);
105
        } else {
106
            $model->loadDefaultValues();
107
108
            return $this->render('create', [
109
                'model' => $model,
110
                'contentTypes' => ContentType::getAllList(false),
111
            ]);
112
        }
113
    }
114
115
    /**
116
     * Creates a new Content model with type choice assistance.
117
     *
118
     * @param int    $flowId
119
     * @param string $type   content type
120
     *
121
     * @return \yii\web\Response|string redirect or render
122
     */
123
    public function actionGenerate($flowId, $type = null)
124
    {
125
        $flow = Flow::findOne($flowId);
126
        if ($flow === null) {
127
            throw new NotFoundHttpException(Yii::t('app', 'The requested flow does not exist.'));
128
        }
129
130
        if (!$flow->canView(Yii::$app->user)) {
131
            throw new \yii\web\ForbiddenHttpException(Yii::t('app', 'You do not have enough rights to view this content.'));
132
        }
133
134
        $contentType = ContentType::findOne($type);
135
        if ($contentType === null) {
136
            $types = ContentType::getAll(false);
137
138
            return $this->render('type-choice', [
139
                'types' => $types,
140
                'flow' => $flowId,
141
            ]);
142
        } else {
143
            $model = new Content(['flow_id' => $flow->id, 'type_id' => $contentType->id]);
144
            if ($model->load(Yii::$app->request->post())) {
145
                if ($model->save()) {
146
                    return $this->redirect(['flow/view', 'id' => $flow->id]);
147
                }
148
            } else {
149
                $model->loadDefaultValues();
150
            }
151
152
            switch ($contentType->input) {
153
                case ContentType::KINDS['FILE']:
154
                    // FILE implies content upload (images/videos)
155
                case ContentType::KINDS['URL']:
156
                    // URL allows content hotlinks, like images
157
                    // There's not much to process, simply input url in data
158
                case ContentType::KINDS['POS']:
159
                    // Latitude & longitude
160
                case ContentType::KINDS['TEXT']:
161
                    // Same as URL, text doesn't require processing
162
                    return $this->render('type/'.$contentType->input, [
163
                            'type' => $contentType,
164
                            'model' => $model,
165
                            'uploadUrl' => Url::to(['content/upload', 'type' => $type]),
166
                            'sideloadUrl' => Url::to(['content/sideload', 'type' => $type]),
167
                        ]);
168
                case ContentType::KINDS['NONE']:
169
                case ContentType::KINDS['RAW']:
170
                    // RAW ContentType doesn't support Content
171
                    // Everything should be handled by ContentType alone
172
                default:
173
                    throw new NotFoundHttpException(Yii::t('app', 'The requested content type is not supported.'));
174
            }
175
        }
176
    }
177
178
    /**
179
     * Receives an uploaded file and responds with filepath.
180
     *
181
     * @api
182
     *
183
     * @param string $type content type
184
     *
185
     * @return string json status
186
     */
187 View Code Duplication
    public function actionUpload($type)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
188
    {
189
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
190
191
        if (!Yii::$app->user->can('upload')) {
192
            return ['success' => false, 'message' => Yii::t('app', 'Not authorized')];
193
        }
194
195
        $model = new Content(['type_id' => $type]);
196
        if (($res = $model->type->upload(UploadedFile::getInstanceByName('content'))) !== false) {
197
            return ['success' => true, 'filepath' => $res['tmppath'], 'duration' => $res['duration'], 'filename' => $res['filename']];
198
        }
199
200
        return ['success' => false, 'message' => $model->type->getLoadError()];
201
    }
202
203
    /**
204
     * Receives an url to download on server -- sideloading.
205
     *
206
     * @api
207
     *
208
     * @param string $type content type
209
     * @param string $url
210
     *
211
     * @return string json status
212
     */
213 View Code Duplication
    public function actionSideload($type, $url)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
214
    {
215
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
216
217
        if (!Yii::$app->user->can('upload')) {
218
            return ['success' => false, 'message' => Yii::t('app', 'Not authorized')];
219
        }
220
221
        $model = new Content(['type_id' => $type]);
222
        if (($res = $model->type->sideload($url)) !== false) {
223
            return ['success' => true, 'filepath' => $res['tmppath'], 'duration' => $res['duration'], 'filename' => $res['filename']];
224
        }
225
226
        return ['success' => false, 'message' => $model->type->getLoadError()];
227
    }
228
229
    /**
230
     * Updates an existing Content model.
231
     * If update is successful, the browser will be redirected to the 'view' page.
232
     *
233
     * @param int $id
234
     *
235
     * @return \yii\web\Response|string redirect or render
236
     */
237
    public function actionUpdate($id)
238
    {
239
        $model = $this->findViewableModel($id, Yii::$app->user);
240
241 View Code Duplication
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
242
            return $this->redirect(['view', 'id' => $model->id]);
243
        } else {
244
            return $this->render('update', [
245
                'model' => $model,
246
                'contentTypes' => ContentType::getAllList(false, true),
247
            ]);
248
        }
249
    }
250
251
    /**
252
     * Deletes an existing Content model.
253
     * If deletion is successful, the browser will be redirected to the 'index' page.
254
     *
255
     * @param int $id
256
     *
257
     * @return \yii\web\Response
258
     */
259
    public function actionDelete($id)
260
    {
261
        $model = $this->findViewableModel($id, Yii::$app->user);
262
263
        $model->delete();
264
265
        return $this->smartGoBack();
266
    }
267
268
    /**
269
     * Renders specific content for preview.
270
     *
271
     * @param int $id content id
272
     *
273
     * @return string HTML render
274
     */
275
    public function actionPreview($id)
276
    {
277
        $model = $this->findViewableModel($id, Yii::$app->user);
278
279
        return $this->renderPartial('preview', [
280
                'type' => $model->type,
281
                'data' => $model->getData(),
282
            ]);
283
    }
284
285
    /**
286
     * Enables or disable a specific content.
287
     *
288
     * @param int $id content id
289
     *
290
     * @return \yii\web\Response
291
     */
292
    public function actionToggle($id)
293
    {
294
        $model = $this->findViewableModel($id, Yii::$app->user);
295
296
        $model->enabled = !$model->enabled;
297
298
        $model->save();
299
300
        return $this->smartGoBack();
301
    }
302
303
    /**
304
     * Finds the Content model based on its primary key value.
305
     * If the model is not found, a 404 HTTP exception will be thrown.
306
     * If the user has not enough rights, a 403 HTTP exception will be thrown.
307
     *
308
     * @param int           $id
309
     * @param \yii\web\User $user
310
     *
311
     * @return Content the loaded model
312
     *
313
     * @throws NotFoundHttpException  if the model cannot be found
314
     * @throws ForbiddenHttpException if the model cannot be accessed
315
     */
316
    protected function findViewableModel($id, $user)
317
    {
318
        $model = $this->findModel($id);
319
        if ($model->canView($user)) {
320
            return $model;
321
        }
322
323
        throw new \yii\web\ForbiddenHttpException(Yii::t('app', 'You do not have enough rights to view this content.'));
324
    }
325
326
    /**
327
     * Finds the Content model based on its primary key value.
328
     * If the model is not found, a 404 HTTP exception will be thrown.
329
     *
330
     * @param int $id
331
     *
332
     * @return Content the loaded model
333
     *
334
     * @throws NotFoundHttpException if the model cannot be found
335
     */
336 View Code Duplication
    protected function findModel($id)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
337
    {
338
        if (($model = Content::findOne($id)) !== null) {
339
            return $model;
340
        } else {
341
            throw new NotFoundHttpException(Yii::t('app', 'The requested content does not exist.'));
342
        }
343
    }
344
}
345