Эта статья была рецензирована Верном Анчетой и Юнесом Рафи . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!
С Laravel довольно легко создавать новостные сайты, блоги или даже форумы, где люди публикуют контент, комментируют или даже отмечают некоторые из этих постов как избранные. Чтобы оживить ситуацию, мы можем сделать приложение более живым, добавив уведомления о действиях других пользователей. В этом руководстве мы будем полагаться на сервис под названием Stream, чтобы добавить эту функцию в наше приложение.
Stream — это API для создания каналов, потоков активности и систем оповещения
API может использоваться со многими языками и платформами. Посетите веб-сайт и нажмите кнопку « Try the API
. Выберите PHP в качестве языка выбора, так как мы будем работать с PHP. Учебник должен дать вам хороший обзор типов уведомлений, которые мы можем получить с помощью Stream. Для Laravel есть официальный пакет, который еще проще интегрировать этот сервис в любое приложение Laravel.
В этом уроке мы собираемся использовать существующий проект, чтобы опробовать Stream API. Просто клонируйте этот репо . Это простой блог Laravel 5.4, где пользователи могут выполнять операции CRUD над сообщениями в блоге. Мы добавим возможность следить за другими пользователями в ближайшее время. Затем мы создадим разделы фидов с различными типами уведомлений, сообщающих нам, кто что сделал и когда. Наше основное внимание в этом уроке будет уделяться людям, создающим новые посты в блоге и следящим друг за другом. Полный код этого урока можно найти здесь .
Настройка проекта
Рекомендуется использовать Homestead Improved для быстрого запуска и запуска в профессиональной среде разработки, которая содержит все, что вам может понадобиться.
git clone https://github.com/vickris/simple-blog
Когда репо настроено локально, мы должны подготовить базу данных перед выполнением любых миграций. Мы будем использовать MySQL для этого урока. После настройки базы данных выполните:
cp .env.example .env
У меня есть раздел подключения к базе данных в моем файле .env
который выглядит следующим образом:
DB_HOST=localhost DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret
Так как это не новая установка Laravel, нам нужно будет запустить composer install
чтобы установить различные пакеты и зависимости для этого проекта:
composer install
Затем запустите:
php artisan migrate php artisan db:seed
Приложение имеет некоторые исходные данные для генерации 10 сообщений. Если мы обслуживаем наше приложение и посещение /posts
, нас должны приветствовать десять постов.
Все готово! Теперь мы можем регистрировать новых пользователей и даже создавать сообщения в блоге. Ссылка для создания нового поста находится в навигационной панели. Давайте добавим возможность следить за другими пользователями. Подписавшись на другого пользователя, мы будем в курсе его действий, т. Е. Создания новых сообщений или подписки других пользователей.
Следующие пользователи
Для этого мы начнем с генерации модели Follow
вместе с миграцией. Заметка. однако для крупных проектов рекомендуется создать followers
и following
таблицы, чтобы упростить запросы:
php artisan make:model Follow -m
Давайте обновим метод up недавно созданной миграции следующим образом:
public function up() { Schema::create('follows', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id')->index(); $table->integer('target_id')->index(); // ID of person being followed $table->timestamps(); }); }
Здесь мы добавляем столбец user_id
потому что user_id
принадлежит пользователю. Давайте теперь запустим команду migrate
чтобы создать следующую таблицу :
php artisan migrate
Нам еще предстоит определить отношения между follows
и users
. Откройте файл модели User
и добавьте отношение:
Приложение / User.php
[...] class User extends Authenticatable { [...] public function follows() { return $this->hasMany(Follow::class); } }
Внутри app/Follow.php
давайте добавим target_id
в список массовых назначаемых атрибутов. Мы также собираемся определить отношения, определяющие, что follow
принадлежит user
:
Приложение / Follow.php
[...] class Follow extends Model { protected $fillable = ['target_id']; public function user() { return $this->belongsTo(User::class); } } [...]
Определив отношения, мы теперь можем добавить возможность следить за другими пользователями. Давайте определим маршруты для последующих и отмененных действий.
[...] Route::group(['middleware' => ['auth']], function () { [...] Route::get('/users', 'FollowController@index'); Route::post('/follow/{user}', 'FollowController@follow'); Route::delete('/unfollow/{user}', 'FollowController@unfollow'); }); [...]
Мы хотим ограничить действия unfollow
и unfollow
для аутентифицированных пользователей, поэтому мы поместили эти маршруты в группу маршрутов с помощью промежуточного программного обеспечения auth
.
Первый маршрут приведет нас на страницу со списком всех пользователей. Далее мы должны создать FollowController
:
php artisan make:controller FollowController
Затем мы определяем действие index
внутри этого контроллера. Он находится внутри действия index
где мы будем извлекать всех пользователей, кроме текущего зарегистрированного пользователя. Нам не нужен сценарий, в котором пользователи могут следить за собой:
приложение / HTTP / Контроллеры / FollowController.php
[...] use App\User; use App\Follow; use Illuminate\Support\Facades\Auth; [...] class FollowController extends Controller { public function index() { return view('users.index', [ 'users' => User::where('id', '!=', Auth::id())->get() ]); } }
У нас все еще нет представления users.index
. Давайте создадим это:
ресурсы / мнение / пользователи / index.blade.php
@extends('layouts.app') @section('content') <div class="container"> <div class="col-sm-offset-2 col-sm-8"> <!-- Following --> <div class="panel panel-default"> <div class="panel-heading"> All Users </div> <div class="panel-body"> <table class="table table-striped task-table"> <thead> <th>User</th> <th> </th> </thead> <tbody> @foreach ($users as $user) <tr> <td clphpass="table-text"><div>{{ $user->name }}</div></td> </tr> @endforeach </tbody> </table> </div> </div> </div> </div> @endsection
Посещая URL /users
, мы должны увидеть имена, принадлежащие зарегистрированным пользователям. Мы хотим добавить кнопку рядом с именем пользователя, чтобы пользователи могли подписываться и отписываться друг от друга.
Давайте обновим только что созданный контроллер, добавив методы follow
и unfollow
. Но перед этим мы должны убедиться, что кто-то еще не следует за другим человеком, прежде чем выполнять последующую операцию, и наоборот. Для этого нам нужно создать небольшую вспомогательную функцию в нашей модели User
:
Приложение / User.php
class User extends Authenticatable { [...] public function isFollowing($target_id) { return (bool)$this->follows()->where('target_id', $target_id)->first(['id']); } }
Теперь мы можем продолжить и кодировать логику для последующих действий и отписаться от действий:
приложение / HTTP / Контроллеры / FollowController.php
class FollowController extends Controller { [...] 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, ]); 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(); $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'); } } }
образомclass FollowController extends Controller { [...] 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, ]); 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(); $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'); } } }
Затем давайте обновим список просмотра для всех пользователей, чтобы рядом с именами пользователей отображались кнопки отслеживания и отмены подписки . Так как нам нужны разные варианты кнопки в зависимости от статуса подписки, мы будем использовать созданную нами вспомогательную функцию. Вставьте блок кода сразу после <td>
отображающего имя в нашем представлении users.index
:
ресурсы / мнение / пользователи / index.blade.php
[...] @if (Auth::User()->isFollowing($user->id)) <td> <form action="{{url('unfollow/' . $user->id)}}" method="POST"> {{ csrf_field() }} {{ method_field('DELETE') }} <button type="submit" id="delete-follow-{{ $user->target_id }}" class="btn btn-danger"> <i class="fa fa-btn fa-trash"></i>Unfollow </button> </form> </td> @else <td> <form action="{{url('follow/' . $user->id)}}" method="POST"> {{ csrf_field() }} <button type="submit" id="follow-user-{{ $user->id }}" class="btn btn-success"> <i class="fa fa-btn fa-user"></i>Follow </button> </form> </td> @endif [...]
Если мы теперь перезагрузим страницу index
пользователей, мы должны увидеть вид, который выглядит следующим образом:
Попробуйте следовать за первым человеком в списке. Обратите внимание на изменение цвета в кнопке.
Представляем Stream
Stream поможет нам получать уведомления, когда кто-то, за кем мы следим, выполняет действие. В этом руководстве мы хотим получать уведомления, когда они создают новое сообщение или подписываются на другого пользователя. Мы также хотим получать уведомления, когда кто-то следит за нами.
Настроить
Давайте установим его через Composer :
composer require get-stream/stream-laravel
Затем мы добавляем GetStream\StreamLaravel\StreamLaravelServiceProvider
в список поставщиков в config/app.php
для регистрации службы:
'providers' => [ // Other providers [...] GetStream\StreamLaravel\StreamLaravelServiceProvider::class, ],
А также создайте для него псевдоним еще в config/app.php
:
'aliases' => [ // other aliases [...] 'FeedManager' => 'GetStream\StreamLaravel\Facades\FeedManager', ],
Затем мы публикуем файл конфигурации с помощью этой команды:
php artisan vendor:publish --provider="GetStream\StreamLaravel\StreamLaravelServiceProvider"
Это создаст файл config/stream-laravel.php
. Мы должны установить наши учетные данные в этом файле, как только они будут созданы на панели мониторинга потоков.
Панель управления потоком
Давайте перейдем к GetStream.io и создадим новое приложение. Вы можете дать приложению любое имя, какое захотите. Для select server location
я выбрал US East
но вы можете выбрать местоположение, которое наиболее близко к вам:
Мы получаем API key
API secret
и API app id
после его создания. Ключи доступны из панели инструментов.
Пока мы находимся на панели инструментов, давайте создадим группы каналов, которые мы хотим для этого приложения. По умолчанию мы должны создать следующее:
-
user
канал, который имеет типflat
( плоские каналы отображают действия без какой-либо группировки, и это тип каналов по умолчанию в Stream ). Этот канал отображает все действия для определенного пользователя. -
timeline
которая также имеет типflat
. Этот канал показывает, что произошло недавно. -
timeline_aggregrated
который имеетaggregated
тип ( агрегированные каналы отображают действия в сгруппированном формате на основе типа действия ). Этот тип канала позволяет пользователю указать формат агрегации. - лента
notification
которая имеет типnotification
. Однако, как и для агрегированных каналов, уведомления могут быть помечены как прочитанные, и вы можете получить счетчик количества невидимых и непрочитанных уведомлений.
Файл конфигурации Stream-Laravel
Мы должны установить полученный API key
API secret
и API app id
в файле config/stream-laravel.php
для взаимодействия с Streams API. Мы должны также установить location
для хорошей меры.
Давайте .env
эти ключи и соответствующие им значения в наш файл .env
затем загрузим их в наш config/stream-laravel.php
с помощью вспомогательного средства env
, предоставляемого Laravel.
.env
STREAM_KEY=xxxxxxxxxx STREAM_SECRET=xxxxxxxxxxxxxxxxxxxxxxxx STREAM_APP_ID=xxxxxx
конфигурации / поток-laravel.php
'api_key' => env('STREAM_KEY'), 'api_secret' => env('STREAM_SECRET'), 'api_app_id' => env('STREAM_APP_ID'), 'location' => 'us-east',
Это должно заставить нас работать с Stream. Давайте теперь рассмотрим некоторые функции, которые поставляются с Stream.
Добавление сообщений в качестве действий — Eloquent ORM Integration
Stream-Laravel обеспечивает мгновенную интеграцию с моделями Eloquent — с помощью GetStream\StreamLaravel\Eloquent\ActivityTrait
мы получаем автоматическое отслеживание модели Post
для пользовательских каналов:
Приложение \ Post.php
class Post extends Model { use \GetStream\StreamLaravel\Eloquent\ActivityTrait; [...]
Каждый раз, когда создается сообщение, оно будет сохраняться в ленте пользователя, который его создал, и когда экземпляр сообщения удаляется, он также удаляется.
Автоматически!
Давайте проверим вещи, создав новый пост. Если теперь мы перейдем к панели управления потоками и перейдем на вкладку « Проводник », то увидим новое действие:
Я предлагаю удалить это действие, так как скоро мы будем обновлять нашу модель Post
, меняя глагол на created
. В нынешнем виде глагол app/Post
. Чтобы удалить занятие, просто установите флажок рядом с занятием, и появится меню с возможностью удалить занятие. Если мы этого не сделаем, мы позже столкнемся с проблемами при отображении каналов.
Вывод
Я должен признать, что настройка Stream заняла некоторое время, но как только мы закончим с этим, мы можем начать использовать различные методы, предлагаемые пакетом stream-laravel, для создания каналов и уведомлений. В следующей части этой серии мы рассмотрим, как настроить наши модели, чтобы их можно было сохранять в лентах как действия. Мы также рассмотрим, как получать различные типы каналов и отображать их в представлении. Будьте на связи!