Статьи

Создание социальной сети с Laravel и Stream? Легко!

В предыдущем посте мы увидели, как добавить следующие функции в приложение Laravel . Мы также рассмотрели, как настроить наше приложение для использования Stream . Эта часть будет сосредоточена на:

  • настройка наших моделей для того, чтобы можно было отслеживать действия.
  • различные типы каналов, которые предоставляет Stream.
  • получать каналы из Stream.
  • рендеринг различных типов каналов в представлении.

Слияние логотипов Laravel и 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, доступна здесь .

Если вы нашли этот урок полезным, нажмите кнопку «Нравится» и не забудьте поделиться с друзьями и коллегами!