В предыдущем посте мы увидели, как добавить следующие функции в приложение Laravel . Мы также рассмотрели, как настроить наше приложение для использования Stream . Эта часть будет сосредоточена на:
- настройка наших моделей для того, чтобы можно было отслеживать действия.
- различные типы каналов, которые предоставляет Stream.
- получать каналы из Stream.
- рендеринг различных типов каналов в представлении.
Поля деятельности
При использовании Stream модели сохраняются в лентах как действия. Деятельность состоит по крайней мере из следующих полей данных: actor
, verb
, object
, time
. Вы также можете добавить больше пользовательских данных, если это необходимо.
- объект является ссылкой на сам экземпляр модели
- актер является ссылкой на атрибут пользователя экземпляра
- глагол представляет собой строковое представление имени класса
Давайте определим глагол активности внутри нашей модели Post
:
[...] class Post extends Model { [...] /** * Stream: Change activity verb to 'created': */ public function activityVerb() { return 'created'; } }
Feed Manager
Мы используем FeedManager
чтобы FeedManager
наше приложение. Stream Laravel поставляется с классом FeedManager
который помогает во всех распространенных операциях подачи. Мы можем получить экземпляр менеджера с FeedManager
который мы FeedManager
в качестве псевдонима фасада ранее в файле config/app.php
.
Предварительно упакованные каналы
Для начала у менеджера есть предварительно настроенные каналы. Мы также можем добавить больше каналов, если они нужны нашему приложению. Три канала делятся на три категории: User Feed
News Feed
Notification Feed
. Канал User feed
, например, хранит все действия для пользователя. Давайте подумаем об этом как о нашей личной странице в Facebook. Мы можем легко получить этот канал от менеджера.
Однако для этого приложения мы больше заинтересованы в получении уведомлений о публикациях, созданных людьми, за которыми мы следим, а также уведомлений о новых подписках, поэтому мы будем просто придерживаться News Feed
и News Feed
Notification Feed
. Для получения дополнительной информации о других типах каналов и о том, как их использовать, перейдите по этой ссылке .
Следовать / Отписаться Функциональность — Использование FeedManager
Нам нужно обновить методы follow
и unfollow
внутри FollowController
, чтобы принять к сведению FeedManager
:
приложение / HTTP / Контроллеры / FollowController.php
[...] public function follow(User $user) { if (!Auth::user()->isFollowing($user->id)) { // Create a new follow instance for the authenticated user Auth::user()->follows()->create([ 'target_id' => $user->id, ]); \FeedManager::followUser(Auth::id(), $user->id); return back()->with('success', 'You are now friends with '. $user->name); } else { return back()->with('error', 'You are already following this person'); } } public function unfollow(User $user) { if (Auth::user()->isFollowing($user->id)) { $follow = Auth::user()->follows()->where('target_id', $user->id)->first(); \FeedManager::unfollowUser(Auth::id(), $follow->target_id); $follow->delete(); return back()->with('success', 'You are no longer friends with '. $user->name); } else { return back()->with('error', 'You are not following this person'); } } [...]
образом[...] public function follow(User $user) { if (!Auth::user()->isFollowing($user->id)) { // Create a new follow instance for the authenticated user Auth::user()->follows()->create([ 'target_id' => $user->id, ]); \FeedManager::followUser(Auth::id(), $user->id); return back()->with('success', 'You are now friends with '. $user->name); } else { return back()->with('error', 'You are already following this person'); } } public function unfollow(User $user) { if (Auth::user()->isFollowing($user->id)) { $follow = Auth::user()->follows()->where('target_id', $user->id)->first(); \FeedManager::unfollowUser(Auth::id(), $follow->target_id); $follow->delete(); return back()->with('success', 'You are no longer friends with '. $user->name); } else { return back()->with('error', 'You are not following this person'); } } [...]
Этот код внутри метода follow
позволяет timeline
ленте текущего пользователя и timeline
timeline_aggregated
следовать личной ленте другого пользователя. В методе unfollow мы отписываемся от личного канала другого пользователя.
Отображение разных типов корма
Чтобы отобразить различные типы каналов, давайте начнем с создания FeedsController
:
php artisan make:controller FeedsController
При чтении данных из каналов действия возвращаются в формате, который не подходит для использования в наших представлениях. Например, деятельность по созданию поста будет выглядеть так:
{'actor': 'User:1', 'verb': 'created', 'object': 'Post:1'}
Это далеко не готово для использования в наших шаблонах. Мы называем процесс загрузки ссылок из базы данных обогащения . Мы обогатим нашу деятельность, прежде чем отображать ее в представлениях.
Новостная лента
Давайте создадим метод newsFeed
внутри этого контроллера для получения этого типа фида. Мы также должны создать приватный метод в этом контроллере, отвечающий за создание экземпляра Enricher class
:
[...] use GetStream\StreamLaravel\Enrich; [...] class FeedsController extends Controller { public function newsFeed(Request $request) { // Timeline feed: $feed = \FeedManager::getNewsFeeds($request->user()->id)['timeline']; // get 25 most recent activities from the timeline feed: $activities = $feed->getActivities(0,25)['results']; $activities = $this->enrich()->enrichActivities($activities); return view('feed.newsfeed', [ 'activities' => $activities, ]); } private function enrich() { return new Enrich; } }
В приведенном выше блоке кода мы вызываем метод getNewsFeeds
из FeedManager
( важно указать формат, который мы хотим получить обратно. В нашем случае нам нужен канал в формате временной шкалы ). После этого мы получаем 25 самых последних действий из канала и затем обогащаем их. Эти действия должны отображаться в представлении newsfeed
которое мы вскоре создадим.
Далее, давайте создадим отображение маршрута для метода newsFeed
, который при посещении приведет нас к просмотру с newsFeed
. Этот маршрут также попадает в группу маршрутов с промежуточным программным обеспечением auth
так как пользователи должны пройти аутентификацию для загрузки канала:
[...] Route::group(['middleware' => ['auth']], function () { [...] Route::get('/feed', 'FeedsController@newsFeed'); }); [...]
шаблонирование
Теперь мы можем визуализировать обогащенные действия в виде:
ресурсы / виды / корм / newsfeed.blade.php
@extends('layouts.app') @section('content') <div class="container"> @if ($activities) <div class="panel panel-default"> <div class="panel-heading"> News Feed </div> <div class="panel-body"> @foreach ($activities as $activity) @include('stream-laravel::render_activity', array('activity'=>$activity)) @endforeach </div> </div> @else <p>You are not following anyone.Follow other users <a href="/users">here</a> in order to see their activities</p> @endif </div> @endsection
stream-laravel::render_activity
представления stream-laravel::render_activity
будет отображать представление activity.$activity["verb"]
stream-laravel::render_activity
activity.$activity["verb"]
с действием в качестве контекста. Чтобы все заработало, нам нужно создать папку активности внутри представлений. После этого мы можем создать партиал для деятельности по созданию постов. Название частичного должно соответствовать глаголу деятельности:
ресурсы / виды / деятельность / created.blade.php
<div class="well well-sm"> <p><small class="text-muted">{{ date('F j, Y, g:i a', strtotime($activity['time'])) }}</small></p> <p><strong>{{ $activity['actor']['name'] }}</strong> created a new post titled <strong>{{ $activity['object']['title'] }}</strong></p> </div>
Посетив URL \feed
, мы сможем увидеть нашу ленту новостей. Первоначально мы увидим текст «Вы ни за кем не следите», поскольку мы еще не интегрировали Stream в наше приложение в то время, когда мы тестировали различные варианты кнопок на основе статуса подписки. Также обратите внимание, что если бы мы не удалили самое первое действие с панели мониторинга потока, на странице возникла бы ошибка с жалобой на отсутствующее представление [.app.\user]
.
Давайте создадим новый пост из нашего аккаунта. Если мы следим за собой из другой учетной записи, эта публикация должна появиться в ленте этой другой учетной записи следующим образом:
На приведенном выше снимке экрана, если пользователь с именем chris
создает еще одно сообщение, новое действие по созданию сообщения из chris
будет отображаться в ленте morris'
:
В качестве альтернативы, вместо создания новых учетных записей и сообщений для проверки этого поведения, мы можем обрезать данные в нашем приложении с панели управления Stream, а затем предварительно заполнить нашу базу данных начальными данными. На рисунке ниже показано, как обрезать данные:
Когда в этот раз мы запустим нашу базу данных, активность пост-записи будет отмечена в Stream:
php artisan migrate:refresh --seed
Затем мы можем следить за некоторыми пользователями, которые были созданы после заполнения базы данных. Если мы сейчас посетим URL \feed
, мы увидим их действия:
Прямо сейчас мы можем получать уведомления только о новых сообщениях, созданных людьми, на которых мы подписаны. Мы также хотим сделать так, чтобы мы получали уведомления о новых подписках.
Фид уведомлений
Для этого давайте начнем с обновления нашей модели Follow
чтобы записать последующие действия
Приложение / Follow.php
class Follow extends Model { use \GetStream\StreamLaravel\Eloquent\ActivityTrait; [...] public function target() { return $this->belongsTo(User::class); } public function activityNotify() { $targetFeed = \FeedManager::getNotificationFeed($this->target_id); return array($targetFeed); } public function activityVerb() { return 'follow'; } public function activityExtraData() { return array('followed' => $this->target, 'follower' => $this->user); }
Метод activityNotify
используется для создания канала уведомлений. Этот тип канала полезен для уведомления определенных пользователей о действии. В нашем случае мы уведомляем пользователя о том, что кто-то последовал за ним. Метод activityExtraData()
позволяет нам хранить больше данных, чем просто основные поля. В нашем случае мы хотим сохранить цель для нового подписчика, а также человека, который следовал за целью.
Давайте продолжим и создадим действие контроллера, маршрут и представление для отображения канала уведомлений:
приложение / HTTP / Контроллеры / feedController
[...] class FeedsController extends Controllers { [...] public function notification(Request $request) { //Notification feed: $feed = \FeedManager::getNotificationFeed($request->user()->id); $activities = $feed->getActivities(0,25)['results']; $activities = $this->enrich()->enrichActivities($activities); return view('feed.notifications', [ 'activities' => $activities, ]); } }
Мы получаем этот канал точно так же, как и канал новостей, с той лишь разницей, что мы вызываем метод FeedManager
в FeedManager
вместо метода getNewsFeeds
.
Давайте теперь создадим отображение маршрута на это действие контроллера:
Route::group(['middleware' => 'auth'], function () { [...] Route::get('/notifications', 'FeedsController@notification'); });
шаблонирование
При отображении канала уведомлений мы будем следовать той же процедуре, что и при отображении ленты новостей, то есть создадим частичное с информацией, которую мы хотим отобразить, затем отобразим частичное в виде. Начнем с создания представления:
ресурсы / виды / корм / notifications.blade.php
@extends('layouts.app') @section('content') <div class="container"> @if ($activities) <div class="panel panel-default"> <div class="panel-heading"> Notification feed </div> <div class="panel-body"> @foreach ($activities as $activity) @foreach ($activity['activities'] as $activity) @include('stream-laravel::render_activity', array('aggregated_activity'=>$activity, 'prefix'=>'notification')) @endforeach @endforeach </div> </div> @else <p>You don't have any follow activities</p> @endif </div> @endsection
Заметьте, нам нужно пройти два уровня, чтобы получить доступ к каналу уведомлений? Это из-за формата данных, который мы получаем после вызова метода getNotificationFeed
. Также обратите внимание, что строка кода для визуализации части имеет префиксный key
значение которого установлено в notification
. Позвольте мне объяснить, что происходит. Для этого приложения нам нужны два разных шаблона для одного и того же действия, то есть следующего действия. Чтобы добиться этого с помощью Stream, мы отправляем третий параметр, чтобы изменить выбор вида. В этом случае мы создадим частичную часть с notification_follow.blade.php
внутри папки активности :
ресурсы / виды / деятельность / notification_follow.blade.php
<div class="well well-sm"> <p><small class="text-muted">{{ date('F j, Y, g:i a', strtotime($activity['time'])) }}</small></p> <p>You are now friends with <strong>{{ $activity['follower']['name'] }}</strong></p> </div>
Если мы посетим URL-адрес /notifications
, мы должны увидеть фид для каждого полученного нами следа и имя человека, который подписался на нас:
На скриншоте и Моррис, и Кевин следовали за мной.
Мы также хотим, чтобы фид последующих действий отображался на нашей странице NewsFeed
. Однако, показывая это, мы хотим сказать, кто с кем подружился. Это причина, по которой нам пришлось придумывать разные частичные элементы для последующей деятельности. Более подробная информация о шаблонах доступна на странице Streams GitHub :
ресурсы / виды / деятельность / follow.blade.php
<div class="well well-sm"> <p><small class="text-muted">{{ date('F j, Y, g:i a', strtotime($activity['time'])) }}</small></p> <p><strong>{{ $activity['actor']['name'] }}</strong> is now friends with <strong>{{ $activity['followed']['name'] }}</strong></p> </div>
Теперь перейдем к URL /feed
. Следующие действия также должны отображаться:
Чтобы упростить навигацию, мы можем добавить ссылки для доступа к новостной ленте и новостным лентам на панели навигации рядом со ссылкой « New Post
:
ресурсы / просмотров / макеты / app.blade.php
<ul class="nav navbar-nav"> <li><a href="{{ url('/posts/create') }}">New Post</a></li> <li><a href="{{ url('/users') }}">Users</a></li> <li><a href="{{ url('/feed') }}">News Feed</a></li> <li><a href="{{ url('/notifications') }}">Notification Feed</a></li> </ul>
Вывод
Stream упрощает добавление каналов в любое приложение по сравнению с кодированием логики с нуля.
Мы можем отслеживать все, что угодно в приложении, даже нравится или комментирует сообщения. Я оставлю это как домашнее задание, чтобы вы могли поиграть с API. Stream также предоставляет низкоуровневый доступ к API для проектов PHP, которые не используют Laravel. Дополнительная информация о том, как напрямую использовать низкоуровневый клиентский API-интерфейс PHP, доступна здесь .
Если вы нашли этот урок полезным, нажмите кнопку «Нравится» и не забудьте поделиться с друзьями и коллегами!