DARK MODE 

Posted on Tuesday, August 2, 2022 by

Create YouTube Clone with Yii (Part 10)

 1) Delete files in storage

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    public function getThumbnailLink()
    {
        return $this->has_thumbnail ? Yii::$app->params['frontendUrl'] . 'storage/thumbs/' . $this->video_id . '.jpg' : '';
    }

    public function afterDelete()
    {
        parent::afterDelete();

        // Delete video file in storage
        $videoPath = Yii::getAlias('@frontend/web/storage/videos/' . $this->video_id . '.mp4');
        unlink($videoPath);

        $thumbnailPath = Yii::getAlias('@frontend/web/storage/thumbs/' . $this->video_id . '.jpg');
        // Delete thumbnail in storage if thumbnail exists
        if (file_exists($thumbnailPath)) {
            unlink($thumbnailPath);
        }
    }
common > models > Video.php

2) Set frontend homepage

Create new controller named VideoController.php in frontend > controllers to return new index page.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php

namespace frontend\controllers;

use yii\web\Controller;

class VideoController extends Controller
{
    public function actionIndex()
    {
        return $this->render('index');
    }
}
frontend > controllers > VideoController.php (new file)

 9
10
11
12
13
14
return [
    'id' => 'app-frontend',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'defaultRoute' => '/video/index',
    'controllerNamespace' => 'frontend\controllers',
frontend > config > main.php

10
11
12
13
14
        'items' => [
            [
                'label' => 'Home',
                'url' => ['/video/index']
            ],
frontend > views > layouts > _sidebar.php

1
This is /video/index.php page
frontend > views > video (new folder) > index.php (new file)


3) Display published video on frontend homepage

 5
..
47
48
49
50
51
use common\models\Video;
..
    public function published()
    {
        // Return published video
        return $this->andWhere(['status' => Video::STATUS_PUBLISHED]);
    }
common > models > query > VideoQuery.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

namespace frontend\controllers;

use yii\web\Controller;
use common\models\Video;
use yii\data\ActiveDataProvider;

class VideoController extends Controller
{
    public function actionIndex()
    {
        $dataProvider = new ActiveDataProvider([
            'query' => Video::find()->published()->latest() // Call mehods in VideoQuery.php
        ]);

        return $this->render('index', [
            'dataProvider' => $dataProvider
        ]);
    }
}
frontend > controllers > VideoController.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?php

/** @var $model \common\models\Video */

?>

<div class="card m-3" style="width: 14rem;">
    <video class="embed-responsive" poster="<?php echo $model->getThumbnailLink() ?>"
        src="<?php echo $model->getVideoLink() ?>"></video>
    <div class="card-body p-2">
        <h6 class="card-title m-0"><?php echo $model->title ?></h6>
        <p class="text-muted card-text m-0">
            <?php echo $model->createdBy->username ?>
        </p>
        <p class="text-muted card-text m-0">
            140 views . <?php echo Yii::$app->formatter->asRelativeTime($model->created_at) ?>
        </p>
    </div>
</div>
frontend > views > video > _video_item.php (new file)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php

/** @var $dataProvider \yii\data\ActiveDataProvier */

echo \yii\widgets\ListView::widget([
    'dataProvider' => $dataProvider, // Display video id
    'itemView' => '_video_item', // Display video in Bootstrap Card from _video_item.php
    'layout' => '<div class="d-flex flex-wrap">{items}</div>{pager}', // Wrap item in _video_item.php in new div
    'itemOptions' => [
        'tag' => false // Remove data-key in div
    ]
]);
frontend > views > video > index.php (new file)


4) Linked video to video view page

This is so when user click on the video thumbnail on homepage, they will redirected to video view page that we will create later.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php

use yii\helpers\Url;

/** @var $model \common\models\Video */

?>

<div class="card m-3" style="width: 14rem;">
    <a href="<?php echo Url::to(['/video/view', 'id' => $model->video_id]) ?>">
        <video class="embed-responsive" poster="<?php echo $model->getThumbnailLink() ?>"
            src="<?php echo $model->getVideoLink() ?>"></video>
    </a>
frontend > views > video > _video_item.php

5) Create video view page


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php

/** @var $model \common\models\Video */
?>

<div class="row">
    <div class="col-sm-8">
        <video class="embed-responsive" poster="<?php echo $model->getThumbnailLink() ?>"
            src="<?php echo $model->getVideoLink() ?>" controls></video>
        <h5 class="mt-2"><?php echo $model->title ?></h5>
        <div class="d-flex justify-content-between align-items-center">
            <div class="text-muted">
                123 views • <?php echo Yii::$app->formatter->asDate($model->created_at) ?>
            </div>
            <div>
                <button class="btn btn-sm btn-outline-primary">
                    <i class="fa-solid fa-thumbs-up"></i> 9
                </button>
                <button class="btn btn-sm btn-outline-secondary">
                    <i class="fa-regular fa-thumbs-down"></i> 3
                </button>
            </div>
        </div>

    </div>
    <div class="col-sm-4"></div>
</div>
frontend > views > video > view.php(new file)

15
..
20
21
22
23
24
..
29
30
31
32
33
34
35
36
<head>
    ..
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css">
    <?php $this->head() ?>
</head>

<body class="d-flex flex-column h-100">
    ..
    <main role="main">
        <div class="content-wrapper p-5">
            <?= $content ?>
        </div>
    </main>

    <?php $this->endBody() ?>
</body>
frontend > views > layouts > blank.php

 8
 9
10
11
..
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
use yii\web\NotFoundHttpException;

class VideoController extends Controller
{
..
    public function actionView($id)
    {
        $this->layout = 'blank';
        $video = Video::findOne($id);

        // Display error if video id does not exist.
        if (!$video) {
            throw new NotFoundHttpException("Video does not exist.");
        }

        // Display video/view.php
        return $this->render('view', [
            'model' => $video
        ]);
    }
}
frontend > controllers > VideoController.php


6) Create video_view table and model

Create new table and migration with the command:

php yii migrate/create create_video_view_table --fields="video_id:string(16):notNull:foreignKey(video),user_id:integer(11):foreignKey(user),created_at:integer(11)"

php yii migrate

Then open Gii and generate a new model for video_view. Use the Gii of backend because we have use it before so the user preferences has been saved.

7) Video views count


  7
..
34
35
36
37
38
39
40
41
42
43
44
use common\models\VideoView;
..
        // Save video views
        $videoView = new VideoView();
        $videoView->video_id = $id;
        $videoView->user_id = \Yii::$app->user->id;
        $videoView->created_at = time();
        $videoView->save();

        // Display video/view.php
        return $this->render('view', [
            'model' => $video
        ]);
frontend > controllers > VideoController.php

117
118
119
120
121
122
123
124
125
126
127
    public function getCreatedBy()
    {
        return $this->hasOne(User::className(), ['id' => 'created_by']);
    }

    /** @return \yii\db\ActiveQuery */

    public function getViews()
    {
        return $this->hasMany(VideoView::class, ['video_id' => 'video_id']);
    }
common > models > Video.php

14
15
16
17
18
19
20
21
22
23
    <div class="card-body p-2">
        <h6 class="card-title m-0"><?php echo $model->title ?></h6>
        <p class="text-muted card-text m-0">
            <?php echo $model->createdBy->username ?>
        </p>
        <p class="text-muted card-text m-0">
            <?php echo $model->getViews()->count() ?> views •
            <?php echo Yii::$app->formatter->asRelativeTime($model->created_at) ?>
        </p>
    </div>
frontend > views > video > _video_item.php

12
13
14
15
            <div class="text-muted">
                <?php echo $model->getViews()->count() ?> views 
                <?php echo Yii::$app->formatter->asDate($model->created_at) ?>
            </div>
frontend > views > video > view.php



No comments:

Post a Comment