DARK MODE 

Posted on Monday, August 1, 2022 by

Create YouTube Clone with Yii (Part 9)

1) Handle video upload error 


78
79
            ['video', 'file', 'extensions' => ['mp4', 'mkv']], // set only accept valid video file
            ['thumbnail', 'image', 'minWidth' => 1280], // set minimum image width
common > models > Video.php
26
27
28
29
30
31
32
33
34
35
36
37
38
        <?php
        $form = \yii\bootstrap4\ActiveForm::begin([
            'options' => ['enctype' => 'multipart/form-data']
        ])
        ?>
        <button class="btn btn-primary btn-file">
            Select File
            <input type="file" name="video" id="videoFile">
        </button>

        <?php \yii\bootstrap4\ActiveForm::end() ?>

        <p><?php echo $form->errorSummary($model) ?></p>
backend > views > video > create.php




2) Video tags

Download https://www.jqueryscript.net/form/Bootstrap-4-Tag-Input-Plugin-jQuery.html and extract tagsinput.css and tagsinput.js into backend > web > tagsinput (new folder). Then creaste new file in backend > assets named TagsInputAsset.php.

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

namespace backend\assets;

use yii\web\AssetBundle;
use yii\web\JqueryAsset;

class TagsInputAsset extends AssetBundle
{
    public $basePath = '@webroot/tagsinput';
    public $baseUrl = '@web/tagsinput';
    public $css = [
        'tagsinput.css',
    ];
    public $js = [
        'tagsinput.js'
    ];
    public $depends = [
        JqueryAsset::class
    ];
}
backend > assets > TagsInputAsset.php (new file)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
..
36
37
38
<?php

use yii\helpers\Html;
use yii\bootstrap4\ActiveForm;

/* @var $this yii\web\View */
/* @var $model common\models\Video */
/* @var $form yii\bootstrap4\ActiveForm */

\backend\assets\TagsInputAsset::register($this);
?>
...
            <?= $form->field($model, 'tags', [
                'inputOptions' => ['data-role' => 'tagsinput']
            ])->textInput(['maxlength' => true]) ?>
backend > views > video > _form.php


3) Change Video index view

Create new file in backend > views > video named _video_item.php.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

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

use \yii\helpers\StringHelper;
use \yii\helpers\Url;

?>

<div class="media">
    <a href="<?php echo Url::to(['/video/update', 'video_id' =>  $model->video_id]) ?>">
        <div style="width:120px">
            <video class="embed-responsive" poster="<?php echo $model->getThumbnailLink() ?>"
                src="<?php echo $model->getVideoLink() ?>"></video>
        </div>
    </a>
    <img src="" alt="" class="mr-3">
    <div class="media-body">
        <h6 class="mt-0"><?php echo $model->title ?></h6>
        <?php echo StringHelper::truncateWords($model->description, 10) ?>
    </div>
</div>
backend > views > video > _video_item.php (new file)

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],

            [
                // Return the view from _video_item.php for Video ID column
                'attribute' => 'video_id',
                'content' => function ($model) {
                    return $this->render('_video_item', ['model' => $model]);
                }
            ],
            [
                // Display status: Published or Unlisted
                'attribute' => 'status',
                'content' => function ($model) {
                    return $model->getStatusLabels()[$model->status];
                }
            ],
            // Display Created At and Updated At date properly
            'created_at:datetime',
            'updated_at:datetime',
            [
                'class' => ActionColumn::className(),
                'urlCreator' => function ($action, Video $model, $key, $index, $column) {
                    return Url::toRoute([$action, 'video_id' => $model->video_id]);
                }
            ],
        ],
    ]); ?>
backend > views > video > index.php



4) Restrict upload for authorized users only


Right now, all of the pages are accessible for everyone even for unauthorized user. We need to fix that.

 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php

namespace backend\controllers;

use Yii;
use yii\web\Controller;
use common\models\Video;
use yii\web\UploadedFile;
use yii\filters\VerbFilter;
use yii\data\ActiveDataProvider;
use yii\filters\AccessControl;
use yii\web\NotFoundHttpException;

/**
 * VideoController implements the CRUD actions for Video model.
 */
class VideoController extends Controller
{
    /**
     * @inheritDoc
     */
    public function behaviors()
    {
        return array_merge(
            parent::behaviors(),
            [
                /* Redirect unauthorized access */
                'access' => [
                    'class' => AccessControl::class,
                    'rules' => [
                        [
                            'allow' => true,
                            'roles' => ['@']
                        ]
                    ]
                ],
                'verbs' => [
                    'class' => VerbFilter::className(),
                    'actions' => [
                        'delete' => ['POST'],
                    ],
                ],
            ]
        );
    }
backend > views > video > index.php

4) Implement frontend layout


Delete the layouts folder in frontend > views and copy the layouts folder containing main.php, blank.php, _sidebar.php, and_header.php from backend, and basically do the same thing we did to the backend with a few modifications. Also copy the site.css from backend and paste it to the frontend and remove the css for icon style.

 6
 7
 8
 9
10
11
use frontend\assets\AppAsset;
use common\widgets\Alert;
use yii\bootstrap4\Breadcrumbs;
use yii\bootstrap4\Html;
use yii\bootstrap4\Nav;
use yii\bootstrap4\NavBar;
frontend > views > layouts > main.php

 6
 7
 8
 9
use frontend\assets\AppAsset;
use yii\helpers\Html;

AppAsset::register($this);
frontend > views > layouts > blank.php
12
13
14
15
16
17
18
19
20
21
22
23
if (Yii::$app->user->isGuest) {
    $menuItems[] = ['label' => 'Signup', 'url' => ['/site/signup']];
    $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']];
} else {
    $menuItems[] = [
        'label' => 'Logout (' . Yii::$app->user->identity->username . ')',
        'url' => ['/site/logout'],
        'linkOptions' => [
            'data-method' => 'post'
        ]
    ];
}
frontend > views > layouts > _header.php

 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
    echo Nav::widget([
        'options' => [
            'class' => 'd-flex flex-column nav-pills'
        ],
        'items' => [
            [
                'label' => 'Home',
                'url' => ['/site/index']
            ],
            [
                'label' => 'History',
                'url' => ['/video/history']
            ]
        ]
    ]);
frontend > views > layouts > _sidebar.php

39
40
41
42
43
44
45
46
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [],
        ],
        'assetManager' => [
            'appendTimestamp' => true
        ]
frontend > config > main.php

 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
main{
    flex: 1;
}

.content-wrapper {
    flex: 1 !important;
}

aside{
min-width: 200px;
}

aside .nav-pills .nav-link {
    border-radius: 0;
    color: #444444;
}

aside .nav-pills .nav-link:hover {
    background: rgba(0, 0, 0, 0.05);
}

aside .nav-pills .nav-link.active, .nav-pills .show > .nav-link {
    background-color: rgba(0, 0, 0, 0.05);
    color: #b90000;
    border-left: 4px solid #b90000;
}
frontend > web > css > site.css


5) Display video uploads based on specific id

Let's say there's another user. Right now, with the current code, when they logged in and view the Video page, they can see the uploads by another account. This is very bad so we need to change this.

 

52
53
54
55
56
    public function actionIndex()
    {
        $dataProvider = new ActiveDataProvider([
            'query' => Video::find()
                ->creator(Yii::$app->user->id),
backend > controllers > VideoController.php

30
31
32
33
34
35
36
37
38
    public function one($db = null)
    {
        return parent::one($db);
    }

    public function creator($userId)
    {
        return $this->andWhere(['created_by' => $userId]);
    }
common > models > query > VideoQuery.php



6) Set default sorting for video uploads display and change Video ID field


52
53
54
55
56
57
    public function actionIndex()
    {
        $dataProvider = new ActiveDataProvider([
            'query' => Video::find()
                ->creator(Yii::$app->user->id)
                ->latest(),
backend > controllers > VideoController.php

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
    public function one($db = null)
    {
        return parent::one($db);
    }

    public function creator($userId)
    {
        return $this->andWhere(['created_by' => $userId]);
    }

    public function latest()
    {
        return $this->orderBy(['created_at' => SORT_DESC]);
    }
}
common > models > query > VideoQuery.php

29
30
31
32
33
34
35
            [
                // Return the view from _video_item.php for Video ID column
                'attribute' => 'title',
                'content' => function ($model) {
                    return $this->render('_video_item', ['model' => $model]);
                }
            ],
backend > views > video > index.php



No comments:

Post a Comment