1) Display channel username and description in video view
13
..
25
26
27
28
29
|
<div class="d-flex justify-content-between align-items-center">
..
</div>
<div>
<p><?php echo $model->createdBy->username ?></p>
<?php echo \yii\helpers\Html::encode($model->description) ?>
</div>
|
frontend > views > video > view.php
2) Link username in video view to channel view
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
|
<?php
namespace frontend\controllers;
use common\models\User;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
class ChannelController extends Controller
{
public function actionView($username)
{
$channel = $this->findChannel($username);
return $this->render('view', [
'channel' => $channel
]);
}
public function findChannel($username)
{
$channel = User::findByUsername($username);
if (!$channel) {
throw new NotFoundHttpException("Channel does not exist.");
}
return $channel;
}
}
|
frontend > controllers >
ChannelController.php (new file)
1
2
3
4
..
26
27
28
29
30
31
32
33
|
<?php
use yii\helpers\Html;
use yii\widgets\Pjax;
..
<div>
<p>
<?php echo Html::a($model->createdBy->username, [
'/channel/view', 'username' => $model->createdBy->username
]) ?>
</p>
<?php echo Html::encode($model->description) ?>
</div>
|
frontend > views > video > view.php
3) Create channel view
1
2
3
4
5
6
7
8
9
10
11
12
|
<?php
?>
<div class="jumbotron">
<h1 class="display-4"><?php echo $channel->username ?></h1>
<hr class="my-4">
<p>It uses utility classes for typography and spacing to space content out within the larger container.</p>
<p class="lead">
<a class="btn btn-danger mr-2" href="#" role="button">Subscribe</a><i class="far fa-bell"></i>
</p>
</div>
|
frontend > views > channel (new folder) >
view.php (new file)
4) Create channel short link
Right now, the channel link looks like
this: /channel/view?username=aliya. We want to shorten it into /c/aliya
just like YouTube.
40
41
42
43
44
45
46
|
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'/c/<username>' => '/channel/view'
],
],
|
frontend > config > main.php
5) Redirect unauthorized user to login page when clicking the Subscribe button
1
2
3
4
5
6
7
|
<?php
use yii\helpers\Url;
?>
<a class="btn btn-danger mr-2" href="<?php echo Url::to(['channel/subscribe', 'username' => $channel->username]) ?>" data-method="post" data-pjax="1">Subscribe</a><i class="far fa-bell"></i>
|
frontend > views > channel >
_subscribe.php (new file)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<?php
use yii\helpers\Url;
use yii\widgets\Pjax;
?>
<div class="jumbotron">
<h1 class="display-4"><?php echo $channel->username ?></h1>
<hr class="my-4">
<?php Pjax::begin();
echo $this->render('_subscribe', [
'channel' => $channel
]);
Pjax::end(); ?>
</div>
|
frontend > views > channel > view.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
27
..
37
38
39
40
..
51
|
<?php
namespace frontend\controllers;
use common\models\User;
use yii\web\Controller;
use yii\filters\AccessControl;
use yii\web\NotFoundHttpException;
class ChannelController extends Controller
{
public function behaviors()
{
return [
// If unathorized user clicked the Subscribe button, they will be redirected to login page
'access' => [
'class' => AccessControl::class,
'only' => ['subscribe'],
'rules' => [
[
'allow' => true,
'roles' => ['@']
]
]
]
];
}
..
public function actionSubscribe($username)
{
$channel = $this->findChannel($username);
}
..
}
|
frontend > controllers > ChannelController.php
6) Create Subscriber table, migration & model
Run these commands to create new table and migration:
php yii migrate/create create_subscriber_table
--fields="channel_id:integer(11):foreignKey(user),user_id:integer(11):foreignKey(user),created_at:integer(11)"
php yii migrate
Then create new model through Gii as we already done before.
7) Working Subscribe button
26
27
..
215
216
217
218
219
220
221
222
|
class User extends ActiveRecord implements IdentityInterface
{
..
public function isSubscribed($userId)
{
return Subscriber::find()->andWhere([
'channel_id' => $this->id,
'user_id' => $userId
])->one();
}
}
|
common > models > User.php
6
7
8
..
11
12
..
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
use yii\web\Controller;
use common\models\Subscriber;
use yii\filters\AccessControl;
..
class ChannelController extends Controller
{
..
public function actionSubscribe($username)
{
$channel = $this->findChannel($username);
// Check if user already subscribed
$userId = \Yii::$app->user->id;
$subscriber = $channel->isSubscribed($userId);
// If user haven't subscribed, then create new Susbcribe
if (!$subscriber) {
$subscriber = new Subscriber();
$subscriber->channel_id = $channel->id;
$subscriber->user_id = $userId;
$subscriber->created_at = time();
$subscriber->save();
}
// If user already subscribed, then unsubscribed
else {
$subscriber->delete();
}
return $this->renderAjax('_subscribe', [
'channel' => $channel
]);
}
|
frontend > controllers > ChannelController.php
To change the state of the button:
7
8
9
|
<a class="btn <?php echo $channel->isSubscribed(Yii::$app->user->id) ? 'btn-secondary' : 'btn-danger' ?> mr-2"
href="<?php echo Url::to(['channel/subscribe', 'username' => $channel->username]) ?>" data-method="post"
data-pjax="1"><?php echo $channel->isSubscribed(Yii::$app->user->id) ? 'Subscribed' : 'Subscribe' ?></a><i class="far fa-bell"></i>
|
frontend > views > channel > _subscribe.php
8) Display Subscriber count
54
55
56
57
58
59
60
61
62
63
64
65
66
|
public function rules()
{
return [
['status', 'default', 'value' => self::STATUS_INACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_INACTIVE, self::STATUS_DELETED]],
];
}
public function getSubscribers()
{
return $this->hasMany(User::class, ['id' => 'user_id'])
->viaTable('subscriber', ['channel_id' => 'id']);
}
|
common > models > User.php
6
7
8
9
10
11
12
13
|
<div class="d-flex align-items-center">
<a class="btn <?php echo $channel->isSubscribed(Yii::$app->user->id) ? 'btn-secondary' : 'btn-danger' ?> mr-2"
href="<?php echo Url::to(['channel/subscribe', 'username' => $channel->username]) ?>" data-method="post"
data-pjax="1"><?php echo $channel->isSubscribed(Yii::$app->user->id) ? 'Subscribed' : 'Subscribe' ?><span
class="ml-2"><?php echo $channel->getSubscribers()->count() ?></span></a><i class="far fa-bell"></i>
</div>
|
frontend > views > channel _subscribe.php
9) Refasctor channel link display
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<?php
namespace common\helpers;
class Html
{
public static function channelLink($user)
{
return \yii\helpers\Html::a(
$user->username,
[
'/channel/view', 'username' => $user->username
],
['class' => 'text-dark']
);
}
}
|
common > helpers (new folder) > Html.php (new file)
27
28
29
30
31
32
|
<div>
<p>
<?php echo \common\helpers\Html::channelLink($model->createdBy) ?>
</p>
<?php echo Html::encode($model->description) ?>
</div>
|
frontend > views > video view.php
10) Display video upload in channel page
7
8
9
10
11
12
13
14
..
31
32
33
34
35
36
37
38
39
40
41
42
43
|
use common\models\Video;
use common\models\Subscriber;
use yii\filters\AccessControl;
use yii\data\ActiveDataProvider;
use yii\web\NotFoundHttpException;
class ChannelController extends Controller
{
..
public function actionView($username)
{
$channel = $this->findChannel($username);
$dataProvider = new ActiveDataProvider([
'query' => Video::find()->creator($channel->id)->published()
]);
return $this->render('view', [
'channel' => $channel,
'dataProvider' => $dataProvider
]);
}
|
frontend > controllers > ChannelController.php
20
21
22
23
24
25
26
27
28
29 | <?php
echo \yii\widgets\ListView::widget([
'dataProvider' => $dataProvider, // Display video id
'itemView' => '../video/_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 > channel > view.php
15
16
17
18 | <h6 class="card-title m-0"><?php echo $model->title ?></h6>
<p class="text-muted card-text m-0">
<?php echo \common\helpers\Html::channelLink($model->createdBy) ?>
</p>
|
frontend > views > video > _video_item.php
No comments:
Post a Comment