khalilcharfi / eloquent-mongodb-viewable

Laravel 包,允许您将视图与 Eloquent 模型关联

v6.0.2 2021-01-02 15:47 UTC

README

Packagist run-tests StyleCI Codecov branch Total Downloads license

这个 Laravel >= 6.0 包允许您将视图与 Eloquent 模型关联。

一旦安装,您可以进行如下操作

// Return total views count
views($post)->count();

// Return total views count that have been made since 20 February 2017
views($post)->period(Period::since('2017-02-20'))->count();

// Return total views count that have been made between 2014 and 2016
views($post)->period(Period::create('2014', '2016'))->count();

// Return total unique views count (based on visitor cookie)
views($post)->unique()->count();

// Record a view
views($post)->record();

// Record a view with a cooldown
views($post)->cooldown(now()->addHours(2))->record();

概览

有时候您不想引入第三方服务如 Google Analytics 来跟踪应用的页面浏览量。这时这个包就非常有用。Eloquent Viewable 允许您轻松地将视图与 Eloquent 模型关联。它设计时考虑了简洁性。

此包将每个视图记录单独存储在数据库中。这种做法的优点是可以进行非常具体的计数。例如,如果我们想知道2018年1月10日至2月17日期间有多少人浏览了某个特定的帖子,我们可以执行以下操作:views($post)->period(Period::create('10-01-2018', '17-02-2018'))->count();。缺点是您的数据库大小可能会随着应用访问者数量的增加而快速增长。

特性

以下是主要特性

  • 将视图与 Eloquent 模型关联
  • 获取总浏览量
  • 获取特定期间的浏览量
  • 获取唯一浏览量
  • 获取可查看类型的浏览量(Eloquent 模型类)
  • 按浏览量排序可查看项
  • 设置浏览之间的冷却时间
  • 内置优雅的缓存包装器
  • 忽略来自爬虫、被忽略的 IP 地址或具有 DNT 标头的请求的浏览量

文档

在本文档中,您可以找到一些关于使用此 Laravel 包的有用信息。

目录

  1. 入门
  2. 使用
  3. 优化
  4. 扩展

入门

要求

此包需要 PHP 7.4+Laravel 6+

Lumen 的支持未维护!

版本信息

安装

首先,您需要通过 Composer 安装此包

composer require khalilcharfi/eloquent-viewable

其次,您可以使用以下命令发布迁移

php artisan vendor:publish --provider="KC\EloquentViewable\EloquentViewableServiceProvider" --tag="migrations"

最后,您需要运行 migrate 命令

php artisan migrate

您可以选择使用以下命令发布配置文件

php artisan vendor:publish --provider="KC\EloquentViewable\EloquentViewableServiceProvider" --tag="config"

手动注册服务提供者

如果您喜欢手动注册包,您可以将以下提供者添加到应用程序的提供者列表中。

// config/app.php

'providers' => [
    // ...
    KC\EloquentViewable\EloquentViewableServiceProvider::class,
];

使用

准备您的模型

要将视图与模型关联,该模型 必须 实现以下接口和特质

  • 接口: KC\EloquentViewable\Contracts\Viewable
  • 特质: KC\EloquentViewable\InteractsWithViews

示例

use Illuminate\Database\Eloquent\Model;
use KC\EloquentViewable\InteractsWithViews;
use KC\EloquentViewable\Contracts\Viewable;

class Post extends Model implements Viewable
{
    use InteractsWithViews;

    // ...
}

记录浏览量

要创建一个视图记录,您可以在流畅的 Views 实例上调用 record 方法。

views($post)->record();

记录访客浏览的最佳位置是在控制器中。例如

// PostController.php
public function show(Post $post)
{
    views($post)->record();

    return view('post.show', compact('post'));
}

注意: 此包默认过滤掉爬虫。测试时请注意这一点,因为Postman例如也是一个爬虫。

设置冷却时间

您可以在Views实例上使用cooldown方法来在视图记录之间添加冷却时间。当您设置冷却时间时,需要指定分钟数。

views($post)
    ->cooldown($minutes)
    ->record();

除了以整数的形式传递分钟数外,您还可以传递一个DateTimeInterface实例。

$expiresAt = now()->addHours(3);

views($post)
    ->cooldown($expiresAt)
    ->record();

工作原理

当使用会话延迟记录视图时,此包还会在访问者的会话中保存视图的快照,并带有过期日期时间。每当访问者再次查看项目时,此包会检查其会话并决定是否应将视图保存到数据库中。

检索浏览量统计

获取总浏览量

views($post)->count();

获取特定期间的浏览量

use KC\EloquentViewable\Support\Period;

// Example: get views count from 2017 upto 2018
views($post)
    ->period(Period::create('2017', '2018'))
    ->count();

此包附带的Period类提供了许多实用功能。Period类的API如下所示

在两个日期时间之间
$startDateTime = Carbon::createFromDate(2017, 4, 12);
$endDateTime = '2017-06-12';

Period::create($startDateTime, $endDateTime);
自一个日期时间以来
Period::since(Carbon::create(2017));
至一个日期时间
Period::upto(Carbon::createFromDate(2018, 6, 1));
自过去以来

使用Carbon::today()作为开始日期时间减去给定单位。

Period::pastDays(int $days);
Period::pastWeeks(int $weeks);
Period::pastMonths(int $months);
Period::pastYears(int $years);
自子类以来

使用Carbon::now()作为开始日期时间减去给定单位。

Period::subSeconds(int $seconds);
Period::subMinutes(int $minutes);
Period::subHours(int $hours);
Period::subDays(int $days);
Period::subWeeks(int $weeks);
Period::subMonths(int $months);
Period::subYears(int $years);

获取总唯一浏览量

如果您只想检索唯一视图数,您可以直接在链中添加unique方法。

views($post)
    ->unique()
    ->count();

按浏览量统计对模型排序

Viewable特性为您模型添加了两个范围:orderByViewsorderByUniqueViews

按浏览量排序

Post::orderByViews()->get(); // descending
Post::orderByViews('asc')->get(); // ascending

按唯一浏览量排序

Post::orderByUniqueViews()->get(); // descending
Post::orderByUniqueViews('asc')->get(); // ascending

按指定期间的浏览量排序

Post::orderByViews('asc', Period::pastDays(3))->get();  // descending
Post::orderByViews('desc', Period::pastDays(3))->get(); // ascending

当然,也可以使用唯一视图变体

Post::orderByUniqueViews('asc', Period::pastDays(3))->get();  // descending
Post::orderByUniqueViews('desc', Period::pastDays(3))->get(); // ascending

按指定集合的浏览量排序

Post::orderByViews('asc', null, 'custom-collection')->get();  // descending
Post::orderByViews('desc', null, 'custom-collection')->get(); // ascending

Post::orderByUniqueViews('asc', null, 'custom-collection')->get();  // descending
Post::orderByUniqueViews('desc', null, 'custom-collection')->get(); // ascending

获取可查看类型的浏览量

如果您想知道特定视图类型有多少次查看,您需要像这样将一个空的Eloquent模型传递到views助手函数中

views(new Post())->count();

您也可以传递一个完全限定的类名。然后包将从这个应用程序容器中解析一个实例。

views(Post::class)->count();
views('App\Post')->count();

查看集合

如果您对同一视图类型的不同视图类型有不同的需求,您可能希望将它们存储在自己的集合中。

views($post)
    ->collection('customCollection')
    ->record();

要检索特定集合中的视图数,您可以重用相同的collection方法。

views($post)
    ->collection('customCollection')
    ->count();

删除时移除浏览量

要自动在删除视图able Eloquent模型时删除所有视图,您可以在模型定义中将removeViewsOnDelete属性设置为true

protected $removeViewsOnDelete = true;

缓存浏览量统计

在某些情况下,缓存视图数可能具有挑战性。例如,周期可能是动态的,这使得缓存不可行。因此,您可以使用内置的缓存功能。

要缓存视图数,只需将remember方法添加到链中。默认生存期是永远。

示例

views($post)->remember()->count();
views($post)->period(Period::create('2018-01-24', '2018-05-22'))->remember()->count();
views($post)->period(Period::upto('2018-11-10'))->unique()->remember()->count();
views($post)->period(Period::pastMonths(2))->remember()->count();
views($post)->period(Period::subHours(6))->remember()->count();
// Cache for 3600 seconds
views($post)->remember(3600)->count();

// Cache until the defined DateTime
views($post)->remember(now()->addWeeks(2))->count();

// Cache forever
views($post)->remember()->count();

优化

基准测试

数据库索引

默认的views表迁移文件已经为viewable_idviewable_type添加了两个索引。

如果您有足够的存储空间,您可以添加另一个索引到visitor列。根据视图数量,这可能在某些情况下加快查询速度。

缓存

缓存视图数可以大大影响您应用程序的性能。您可以在这里阅读有关缓存视图数的文档。

使用remember方法只会缓存由count方法制作的视图数。因为orderByViewsorderByUnique查询范围只添加一些东西到查询构建器,所以它们不使用这些值。为了优化这些查询,您可以在您的视图able数据库表中添加一个额外的列或多个列来包含这些计数。

示例:我们希望根据独特视图数对博客文章进行排序。首先想到的可能是使用orderByUniqueViews查询范围。

$posts = Post::latest()->orderByUniqueViews()->paginate(20);

当您存储了大量的视图时,此查询相当慢。为了加快速度,您可以在例如的posts表中添加一个unique_views_count列。我们将不得不定期使用独特视图数更新此列。这可以通过使用计划的Laravel命令轻松实现。

可能有一种更快的方法来做这件事,但这样的命令可能像

$posts = Post::all();

foreach($posts as $post) {
    $post->unique_views_count = views($post)->unique()->count();
}

待更新!Laravel 有一个很不错的块和光标功能,这可能非常有用。

扩展

如果您想用自己的实现扩展或替换其中一个核心类,您可以覆盖它们

  • KC\EloquentViewable\Views
  • KC\EloquentViewable\View
  • KC\EloquentViewable\Visitor
  • KC\EloquentViewable\CrawlerDetectAdapter

注意:别忘了所有自定义类都必须实现它们原始的接口

自定义访客信息

Visitor 类负责向 Views 构建器提供有关当前访问者的信息。以下信息会被提供

  • 一个唯一的标识符(存储在cookie中)
  • IP地址
  • 检查Do No Track头
  • 检查爬虫

默认的 Visitor 类从请求中获取其信息。因此,您可能会在使用 RESTful API 通过 Views 构建器时遇到一些问题。要解决这个问题,您需要提供有关访问者的自己的数据。

您可以在全局或局部覆盖 Visitor 类。

创建自己的 Visitor

在您的 Laravel 应用程序中创建自己的 Visitor 类并实现 KC\EloquentViewable\Contracts\Visitor 接口。创建接口所需的方法。

或者,您可以扩展此包附带默认的 Visitor 类。

全局

只需将您的自定义 Visitor 实现绑定到 KC\EloquentViewable\Contracts\Visitor 合约。

$this->app->bind(
    \KC\EloquentViewable\Contracts\Visitor::class,
    \App\Services\Views\Visitor::class
);

局部

您还可以通过在 Views 构建器上使用 useVisitor 设置器方法来设置访问者实例。

use App\Services\Views\Visitor;

views($post)
    ->useVisitor(new Visitor()) // or app(Visitor::class)
    ->record();

使用您自己的 Views Eloquent 模型

将您的自定义 Views 实现绑定到 \KC\EloquentViewable\Contracts\Views

更改以下代码片段,并将其放置在服务提供者的 register 方法中(例如 AppServiceProvider)。

$this->app->bind(
    \KC\EloquentViewable\Contracts\Views::class,
    \App\Services\Views\Views::class
);

使用您自己的 View Eloquent 模型

将您的自定义 View 实现绑定到 \KC\EloquentViewable\Contracts\View

更改以下代码片段,并将其放置在服务提供者的 register 方法中(例如 AppServiceProvider)。

$this->app->bind(
    \KC\EloquentViewable\Contracts\View::class,
    \App\Models\View::class
);

使用自定义爬虫检测器

将您的自定义 CrawlerDetector 实现绑定到 \KC\EloquentViewable\Contracts\CrawlerDetector

更改以下代码片段,并将其放置在服务提供者的 register 方法中(例如 AppServiceProvider)。

$this->app->singleton(
    \KC\EloquentViewable\Contracts\CrawlerDetector::class,
    \App\Services\Views\CustomCrawlerDetectorAdapter::class
);

Views 类添加宏

use KC\EloquentViewable\Views;

Views::macro('countAndRemember', function () {
    return $this->remember()->count();
});

现在您可以使用以下简写

views($post)->countAndRemember();

Views::forViewable($post)->countAndRemember();

升级

请参阅 UPGRADING 以获取详细的升级指南。

变更日志

请参阅 CHANGELOG 以获取有关最近更改的更多信息。

贡献

请参阅 CONTRIBUTING 以获取详细信息。

鸣谢

请参阅参与此项目的 贡献者列表

有用的资源

替代方案

请随意添加更多替代方案!

许可证

本项目采用 MIT 许可证 - 有关详细信息,请参阅 LICENSE 文件。