get-stream / stream-doctrine
使用 getstream.io 和 Doctrine 构建新闻源和活动源
Requires
- php: >=8.0
- doctrine/orm: ^2.14.1
- get-stream/stream: ^7.0.1
Requires (Dev)
- cakephp/chronos: ^2.3
- friendsofphp/php-cs-fixer: ^3.14.0
- phpunit/phpunit: ^9.6.3
This package is auto-updated.
Last update: 2024-08-25 16:44:02 UTC
README
stream-doctrine 是一个包,它将您的 Doctrine 实体与 Stream 集成。
您可以在 https://getstream.io/get_started 注册 Stream 账户。
注意,还有一个更低级别的 PHP - Stream 集成 库,它适用于所有 PHP 应用程序。
💡 此库是为 Feeds 产品构建的。Chat 产品可以在 这里 找到。
构建活动源、新闻源等
您可以构建
- 活动源 - 如在 GitHub 上所见
- 类似 Twitter 的源
- Instagram / Pinterest 照片源
- 类似 Facebook 的新闻源
- 通知系统
- 更多...
安装
Composer
composer require get-stream/stream-doctrine
Composer 将自动安装我们最新的版本。
PHP 兼容性
当前版本需要 PHP 8.0
或更高版本,并依赖于 doctrine/orm
版本 2.14
或更高。
有关如何构建和针对不同的 PHP 版本进行测试的详细信息,请参阅 GitHub 构建配置。
GetStream.io 仪表板
现在,登录到 GetStream.io 并在仪表板中创建一个应用程序。
获取 API 密钥、API 密钥和 API 应用程序 ID,它们显示在您的仪表板中。
Stream-Doctrine 设置
设置
要将此插件注册到 Doctrine ORM 中,您需要在 EntityManager 上注册一个 ModelListener
,如下所示
$client = new GetStream\Stream\Client($apiKey, $apiSecret); $manager = new GetStream\Doctrine\FeedManager($client); $listener = new GetStream\Doctrine\ModelListener($manager); $entityManager ->getConfiguration() ->getEntityListenerResolver() ->register($listener);
Stream-Doctrine 的功能
实体集成
Stream-Doctrine 提供了与 Doctrine 实体的即时集成 - 实现了 GetStream\Doctrine\Activity
接口并添加了 EntityListener,这将自动跟踪您的模型到用户源。
例如
/** * @ORM\Table(name="pins") * @ORM\EntityListeners({"\GetStream\Doctrine\ModelListener"}) */ class Pin implements Activity { use ActivityTrait; }
每当创建一个 Pin 时,它将被存储在创建它的用户的源中,当删除 Pin 实例时,它也将被删除。
自动!
活动字段
模型以活动形式存储在源中。活动由以下数据字段组成: actor、verb、object、time。如果需要,您还可以添加更多自定义数据。
object 是实体实例本身的引用 actor 是实例的用户属性引用 verb 是类名的字符串表示 time 是活动发生时的 DateTimeInterface 对象。这通常是实体的 created_at
或类似属性。
在实现 ActivityInterface 时对实体类做出了一些假设
- 实体有一个标识符(这适用于每个实体)。
- 实体与某个用户或“actor”有一个 *-to-one 关系。
- 实体有一个时间戳列(例如
created_at
)。
您可以通过实现后续解释的特定方法来更改实体实例作为活动的存储方式。
下面是一个完整的活动类型实体的示例:
class Pin implements ActivityInterface { use ActivityTrait; /** * Each pin is created by someone. * * @var User * * @ORM\ManyToOne(targetEntity="User", fetch="EXTRA_LAZY") * @ORM\JoinColumn(name="creator_id", referencedColumnName="id") */ private $creator; /** * @ORM\Column(type="datetime_immutable", name="created_at") */ private $createdAt; /** * @return string */ public function activityVerb() { return 'pin'; } /** * @return string */ protected function activityId() { return $this->id; } /** * @return string */ public function activityActorId() { return $this->creator->id(); } /** * @return string */ public function activityActor() { return User::class.':'.$this->activityActorId(); } /** * @return DateTimeInterface */ public function activityTime() { return $this->createdAt; }
您可以根据您的需求或实体实现更改每个 activity*
方法。
活动额外数据
通常,您可能想要存储比基本字段更多的数据,例如用于自定义排名或聚合。您可以通过在实体中实现 activityExtraData
方法来实现这一点。
注意:数据将使用 json_encode 函数进行序列化,因此它需要是该函数的有效输入。
class Tweet implements ActivityInterface { use ActivityTrait; public function activityExtraData() { return ['is_retweet' => $this->isRetweet()]; } }
Feed 管理器
stream-doctrine
包含一个 FeedManager 类(实现 FeedManagerInterface),它有助于处理所有常见的饲料操作。在实例化时,FeedManager 需要一个配置好的 GetStream\Stream\Client
对象。
预配置的 Feeds
为了帮助您开始,管理器已经预配置了 feeds。如果您的应用程序需要,您可以添加更多 feeds。这三个 feeds 分为三个类别。
用户 Feed
用户 Feed 存储了用户的全部活动。把它想象成您个人的 Facebook 页面。您可以从管理器轻松获取此 feed。
/** @var $feed GetStream\Stream\Feed */ $feed = $feedManager->getUserFeed($userId);
新闻 Feed
新闻 Feeds 存储了您关注的人的活动。您可以使用以下方式设置新闻 Feeds 的名称
$feedManager->setNewsFeeds(['timeline', 'timeline_aggregated']);
然后您可以通过 ArrayAccess 类似的方式访问这些 feed
$timelineFeed = $feedManager->getNewsFeed($userId)['timeline']; $aggregatedTimelineFeed = FeedManager::getNewsFeed($userId)['timeline_aggregated'];
用户 Feed 和新闻 Feed 都是以下方法的简写
$feed = $feedManager->getFeed('user', $userId); $feed = $feedManager->getFeed('timeline', $userId); $feed = $feedManager->getFeed('timeline_aggregated', $userId);
通知 Feed
通知 Feed 可以用于构建通知功能。
下面我们展示了如何读取通知 feed 的示例。
$notificationFeed = $feedManager->getNotificationFeed($user->id);
默认情况下,通知 feed 将为空。当您的模型创建时,您可以指定要通知哪些用户。在转发的例子中,您可能想要通知父推文的用户。
class Tweet implements ActivityInterface { use ActivityTrait; /** * @return array */ public function activityNotify() { if ($this->isRetweet()) { return ['notification:'.$this->parent()->user()->id()]; } return []; }
另一个例子是关注一个用户。您通常会想通知被关注的用户。
class Follow implements ActivityInterface { use ActivityTrait; /** * @return array */ public function activityNotify() { return ['notification:'.$this->target()->id()]; } }
关注 Feed
要创建新闻 Feeds,您需要通知系统有关关注关系。管理器包含让用户的新闻 Feeds 关注另一个用户的 feed 的方法。此代码允许当前用户的新闻 Feeds 关注目标用户个人的 feed。
/** @var GetStream\Doctrine\FeedManager $manager */
$manager->setNewsFeeds(['timeline', 'timeline_aggregated']);
$manager->followUser($userId, $targetId);
// Same as:
$targetFeed = $client->feed('user', $targetId);
$feed1 = $client->feed('timeline', $userId);
$feed2 = $client->feed('timeline_aggregated', $userId);
$feed1->follow($targetFeed->getSlug(), $targetFeed->getId());
$feed2->follow($targetFeed->getSlug(), $targetFeed->getId());
显示新闻 feed
活动丰富化
当您从使用 stream-doctrine
创建活动的 feeds 中读取数据时,活动将看起来像这样
{ "actor": "User:1", "verb": "like", "object": "Like:42" }
这远远没有准备好在您的模板中使用。我们称从数据库加载引用的过程为丰富化。下面是一个示例。
use GetStream\Doctrine\Enrich; $feed = $feedManager->getUserFeed($userId); $activities = $feed->getActivities(0, 25)['results']; $enricher = new Enrich(); $activities = $enricher->enrichActivities($activities);
自定义丰富化
有时您可能想要自定义丰富化的方式。如果您将模型实例的引用存储为自定义字段(使用 activityExtraData()
方法),则可以使用 Enrich
类来为您处理。
class Pin implements ActivityInterface { use ActivityTrait; public function activityExtraData() { return ['parent_tweet' => self::class.':'.$this->parent()->id()]; } }
告诉丰富化器将 parent_tweet
字段丰富为一个完整的实体对象
$enricher = (new Enrich()->setEnrichingFields(['actor', 'object', 'parent_tweet'])); $activities = $feed->getActivities(0,25)['results']; $activities = $enricher->enrichActivities($activities);
完整文档和低级别 API 访问
需要时,您还可以直接使用 低级别 PHP API。文档可在 Stream 网站 上找到。
/** @var $client GetStream\Stream\Client */
$client = $feedManager->getClient();
版权和许可信息
版权(c)2014-2022 Stream.io Inc,以及个别贡献者。保留所有权利。
有关此软件的历史、使用条款和条件以及所有保证的放弃,请参阅“LICENSE”文件。