PHPackages                             therealedatta/fork-cyrildewit-eloquent-viewable-tags - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. therealedatta/fork-cyrildewit-eloquent-viewable-tags

ActiveLibrary[Database &amp; ORM](/categories/database)

therealedatta/fork-cyrildewit-eloquent-viewable-tags
====================================================

Fork from cyrildewit/eloquent-viewable applying tags pull request. ABANDONED.

v1.0.0(4y ago)0151Apache-2.0PHPPHP ^7.0

Since Jul 30Pushed 4y ago2 watchersCompare

[ Source](https://github.com/therealedatta/fork-cyrildewit-eloquent-viewable-tags)[ Packagist](https://packagist.org/packages/therealedatta/fork-cyrildewit-eloquent-viewable-tags)[ Docs](https://github.com/cyrildewit/eloquent-viewable)[ RSS](/packages/therealedatta-fork-cyrildewit-eloquent-viewable-tags/feed)WikiDiscussions main Synced 2d ago

READMEChangelog (1)Dependencies (16)Versions (2)Used By (0)

Eloquent Viewable
=================

[](#eloquent-viewable)

[![Packagist](https://camo.githubusercontent.com/d5e6d8bd2faf5d627e53ff921a59c5f4c74396857141aeb7539f366b0d0dfa25/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f637972696c64657769742f656c6f7175656e742d7669657761626c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/cyrildewit/eloquent-viewable)[![Travis branch](https://camo.githubusercontent.com/e2c8f766071edca9065fd567e71b2413bacef401ef9d5d3fa5321b20c13e8413/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f637972696c64657769742f656c6f7175656e742d7669657761626c652f322e302e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/cyrildewit/eloquent-viewable)[![StyleCI](https://camo.githubusercontent.com/cc44bc4841809fd391c168d3a1b125f3733649fa5b77572519e167e78b7163d0/68747470733a2f2f7374796c6563692e696f2f7265706f732f39343133313630382f736869656c643f7374796c653d666c61742d737175617265)](https://styleci.io/repos/94131608)[![Codecov branch](https://camo.githubusercontent.com/d493e0b78b08e741dea69d2e67df97306d8b5865375b1445e976f7fb4d8aa284/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f637972696c64657769742f656c6f7175656e742d7669657761626c652f322e302e7376673f7374796c653d666c61742d737175617265)](https://codecov.io/gh/cyrildewit/eloquent-viewable)[![Total Downloads](https://camo.githubusercontent.com/b92197f62981b7b8d9b859105903ba9e32cd5e14b02eb234c496821ac984fdb2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f637972696c64657769742f656c6f7175656e742d7669657761626c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/cyrildewit/eloquent-viewable)[![license](https://camo.githubusercontent.com/385f9aef33368555fce440a3c3dbc368a552e17168ca819feaef3ae562b6bb6d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f637972696c64657769742f656c6f7175656e742d7669657761626c652e7376673f7374796c653d666c61742d737175617265)](https://github.com/cyrildewit/eloquent-viewable/blob/master/LICENSE.md)

> **Note:** This is an unstable branch!

This Laravel &gt;= 5.5 package allows you to associate views with Eloquent models.

Once installed you can do stuff like this:

```
// Get the total number of views
$post->getViews();

// Get the total number of views since the given date
$post->getViews(Period::since(Carbon::parse('2014-02-23 00:00:00')));

// Get the total number of views between the given date range
$post->getViews(Period::create(Carbon::parse('2014-00-00 00:00:00'), Carbon::parse('2016-00-00 00:00:00')));

// Get the total number of views in the past 6 weeks (from today)
$post->getViews(Period::pastWeeks(6));

// Get the total number of views in the past 2 hours (from now)
$post->getViews(Period::subHours(2));

// Store a new view in the database
$post->addView();
```

Overview
--------

[](#overview)

Eloquent Viewable is a flexible and easy to use Laravel package to associate views with Eloquent Models. It's designed for large and small projects. Instead of having a simple counter that increments by each view, this package will provide you a full history of the views.

This package is not built with the intent to collect analytical data. It is made to simply store the views of a Laravel Eloquent model. You would this package for models like: Post, Video, Course and Hotel, but of course, you can use this package as you want.

### Features

[](#features)

Here are some of the main features:

- Associate views with Eloquent models
- Get the total number of (unique) views
- Get the total number of (unique) views since a specific date
- Get the total number of (unique) views upto a specific date
- Get the total number of (unique) views between two dates
- Get the total number of (unique) views in the past `days`, `weeks`, `months` and `years` from today
- Get the total number of (unique) views in the past `seconds`, `minutes`, `hours`, `days`, `weeks`, `months` and `years` from now
- Cache the retrieved views counts
- Queue the views before saving them in the database to prevent slow requests

Feature requests are very welcome! Create an issue with \[Feature Request\] as prefix or send a pull request.

Documentation
-------------

[](#documentation)

In this documentation, you will find some helpful information about the use of this Laravel package.

### Table of contents

[](#table-of-contents)

1. [Getting Started](#getting-started)
    - [Requirements](#requirements)
    - [Installation](#installation)
2. [Usage](#usage)
    - [Preparing your models](#preparing-your-models)
    - [Storing views](#storing-views)
    - [Storing views with expiry date](#storing-views-with-expiry-date)
    - [Storing views under a tag](#storing-views-under-a-tag)
    - [Retrieving views counts](#retrieving-views-counts)
    - [Order models by views count](#order-models-by-views-count)
    - [`Views` helper](#views-helper)
3. [Configuration](#configuration)
    - [Queue the ProcessView job](#queue-the-processview-job)
    - [Extending](#extending)
4. [Recipes](#recipes)
    - [Creating helper methods for frequently used period formats](#creating-helper-methods-for-frequently-used-period-formats)

Getting Started
---------------

[](#getting-started)

### Requirements

[](#requirements)

The Eloquent Viewable package requires **PHP 7+** and **Laravel 5.5+**.

Lumen is not supported!

#### Version information

[](#version-information)

VersionIlluminateStatusPHP Version&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD3.05.5 - 5.7*In Development*&gt;= 7.1.02.05.5 - 5.7Active support&gt;= 7.0.0=======3.05.5 - 5.6Active support&gt;= 7.0.02.05.5 - 5.6Active support&gt;= 7.0.0> > > > > > > feature/tags | 1.0 | 5.5 - 5.6 | Bug fixes only | &gt;= 7.0.0 |

### Installation

[](#installation)

You can install this package via composer using:

```
composer require cyrildewit/eloquent-viewable
```

Optionally, you can add the service provider in the `config/app.php` file. Otherwise this can be done via automatic package discovery.

```
// config/app.php

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

You can publish the migration with:

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

After publishing the migration file you can create the `views` table by running the migrations. However, if you already have a table named `views`, you can change this name in the config. Search for 'models-&gt;view-&gt;table\_name' and change the value to something unique.

```
php artisan migrate
```

You can publish the config file with:

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

Usage
-----

[](#usage)

In the following sections, you will find information about the usage of this package.

### Preparing your models

[](#preparing-your-models)

To make an Eloquent model viewable just add the `Viewable` trait to your model definition. This trait provides various methods to allow you to save views, retrieve views counts and order your items by views count.

```
use Illuminate\Database\Eloquent\Model;
use CyrildeWit\EloquentViewable\Viewable;

class Post extends Model
{
    use Viewable;

    // ...
}
```

### Storing views

[](#storing-views)

Adding a new view to a model can be achieved really easy by calling the `->addView()` method on your viewable model.

The best place where you should put it is inside your controller. If you're following the CRUD standard, it would be the `@show` method.

```
$post->addView();
```

A `PostController` might look something like this:

```
// ...
public function show(Post $post)
{
    $post->addView();

    return view('blog.post', compact('post'));
}
// ...
```

**Note:** If you want to queue this job, you can turn this on in the configuration! See the [Queue the ProcessView job](#queue-the-processview-job) section!

### Storing views with expiry date

[](#storing-views-with-expiry-date)

If you want to add a delay between views from the same session, you can use the available `addViewWithExpiryDate` on your viewable model.

```
$post->addViewWithExpiryDate(Carbon::now()->addHours(2));
```

This method will add a new view to your model and it will add a record in the user's session. If you call this method multiple times, you will see that views count will not increment. After the current date time has passed the expiry date, a new view will be stored.

### Storing views under a tag

[](#storing-views-under-a-tag)

In some cases you might want to have multiple counters for a viewable model. This can be easily achieved by passing an additional argument to the `addView` method.

```
$post->addView('customTag');
```

And with expiry date:

```
$post->addViewWithExpiryDate(Carbon::now()->addHours(2), 'customTag')
```

### Retrieving views counts

[](#retrieving-views-counts)

After adding the `Viewable` trait to your model, you will be able to call `getViews()` and `getUniqueViews()` on your viewable model. Both methods accepts an optional `Period` instance.

```
/**
 * Get the total number of views.
 *
 * @param  \CyrildeWit\EloquentViewable\Support\Period
 * @return int
 */
public function getViews($period = null): int;

/**
 * Get the total number of unique views.
 *
 * @param  \CyrildeWit\EloquentViewable\Support\Period
 * @return int
 */
public function getUniqueViews($period = null) : int;
```

#### Period class

[](#period-class)

*Be aware that the following code isn't valid PHP syntax!*

```
// Create a new Period instance.
Period::create(DateTime $startDateTime = null, DateTime $endDateTime = null);

// Create a new Period instance with only a start date time.
Period::since(DateTime $startDateTime);

// Create a new Period instance with only a end date time.
Period::upto(DateTime $endDateTime);
```

```
// Period instance with a start date time of today minus the given days.
Period::pastDays(int $days);

// Period instance with a start date time of today minus the given weeks.
Period::pastWeeks(int $weeks);

// Period instance with a start date time of today minus the given months.
Period::pastMonths(int $months);

// Period instance with a start date time of today minus the given years.
Period::pastYears(int $years);
```

```
// Period instance with a start date time of now minus the given seconds.
Period::subSeconds(int $seconds);

//Period instance with a start date time of now minus the given minutes.
Period::subMinutes(int $minutes);

// Period instance with a start date time of now minus the given hours.
Period::subHours(int $hours);

// Period instance with a start date time of now minus the given days.
Period::subDays(int $days);

// Period instance with a start date time of now minus the given weeks.
Period::subWeeks(int $weeks);

// Period instance with a start date time of now minus the given months.
Period::subMonths(int $months);

// Period instance with a start date time of now minus the given years.
Period::subYears(int $years);
```

#### Examples

[](#examples)

```
$post->getViews();

$post->getViews(Period::since(Carbon::parse('2007-05-21 12:23:00')));

$post->getViews(Period::upto(Carbon::parse('2013-05-21 00:00:00')));

$post->getViews(Period::create(Carbon::parse('2014-00-00 00:00:00'), Carbon::parse('2016-00-00 00:00:00')));
```

```
$post->getUniqueViews();

$post->getUniqueViews(Period::since(Carbon::parse('2007-05-21 12:23:00')));

$post->getUniqueViews(Period::upto(Carbon::parse('2013-05-21 00:00:00')));

$post->getUniqueViews(Period::create(Carbon::parse('2014-00-00 00:00:00'), Carbon::parse('2016-00-00 00:00:00')));
```

```
$post->getViews(Period::pastDays(5));

$post->getViews(Period::pastWeeks(6));

$post->getViews(Period::pastMonths(8));

$post->getViews(Period::pastYears(3));
```

```
$post->getUniqueViews(Period::pastDays(5));

$post->getUniqueViews(Period::pastWeeks(6));

$post->getUniqueViews(Period::pastMonths(8));

$post->getUniqueViews(Period::pastYears(3));
```

```
$post->getViews(Period::subSeconds(30));

$post->getViews(Period::subMinutes(15));

$post->getViews(Period::subHours(8));

$post->getViews(Period::subDays(5));

$post->getViews(Period::subWeeks(6));

$post->getViews(Period::subMonths(8));

$post->getViews(Period::subYears(3));
```

```
$post->getUniqueViews(Period::subSeconds(30));

$post->getUniqueViews(Period::subMinutes(15));

$post->getUniqueViews(Period::subHours(8));

$post->getUniqueViews(Period::subDays(5));

$post->getUniqueViews(Period::subWeeks(6));

$post->getUniqueViews(Period::subMonths(8));

$post->getUniqueViews(Period::subYears(3));
```

### Order models by views count

[](#order-models-by-views-count)

#### Retrieve Viewable models by views count

[](#retrieve-viewable-models-by-views-count)

```
$sortedPosts = Post::orderByViewsCount()->get(); // desc
$sortedPosts = Post::orderByViewsCount('asc')->get();
```

#### Retrieve Viewable models by unique views count

[](#retrieve-viewable-models-by-unique-views-count)

```
$sortedPosts = Post::orderByUniqueViewsCount()->get(); // desc
$sortedPosts = Post::orderByUniqueViewsCount('asc')->get();
```

### `Views` helper

[](#views-helper)

#### Saving views

[](#saving-views)

```
use CyrildeWit\EloquentViewable\Views;

Views::create($post)->addView();
```

#### Saving views with expiry date

[](#saving-views-with-expiry-date)

```
use CyrildeWit\EloquentViewable\Views;

Views::create($post)->addViewWithExpiryDate(Carbon::now()->addHours(2));
```

#### Saving views under a tag

[](#saving-views-under-a-tag)

```
use CyrildeWit\EloquentViewable\Views;

// addView method
Views::create($post)->addView('customTag');

// addViewWithExpiryDate method
Views::create($post)->addViewWithExpiryDate(Carbon::now()->addHours(2), 'customTag');
```

#### Retrieving views counts

[](#retrieving-views-counts-1)

```
use CyrildeWit\EloquentViewable\Views;

Views::create($post)->getViews();
```

#### Get views by viewable type

[](#get-views-by-viewable-type)

To get the total number of views by a viewable type, you can use one of following methods.

```
use CyrildeWit\EloquentViewable\Views;

Views::getViewsByType($post);
Views::getViewsByType(Post::class);
Views::getViewsByType('App\Post');
```

#### Get most viewed viewables by type

[](#get-most-viewed-viewables-by-type)

```
use CyrildeWit\EloquentViewable\Views;

// Get top 10 most viewed by type
Views::getMostViewedByType($post, 10);
Views::getMostViewedByType(Post::class, 10);
Views::getMostViewedByType('App\Post', 10);

// Get top 10 lowest viewed by type
Views::getLowestViewedByType($post, 10);
Views::getLowestViewedByType(Post::class, 10);
Views::getLowestViewedByType('App\Post', 10);
```

#### Get the views count of viewables per period

[](#get-the-views-count-of-viewables-per-period)

Don't confuse this method with the `Period` class!

```
use CyrildeWit\EloquentViewable\Views;

Views::getViewsPerPeriod('minute', 30); // per 30 minutes
Views::getViewsPerPeriod('hour', 12); // per 12 hours
Views::getViewsPerPeriod('day'); // per day
Views::getViewsPerPeriod('week', 2); // per 2 weeks
Views::getViewsPerPeriod('month'); // per month
Views::getViewsPerPeriod('year'); // per month
```

Configuration
-------------

[](#configuration)

### Queue the ProcessView job

[](#queue-the-processview-job)

When calling the `->addView()` method on your model, it will save a new view in the database with some data. Because this can slow down your application, you can turn queuing on by changing the value of `store_new_view` under `jobs` in the configuration file. Make sure that your app is ready for queuing. If not, see the official [Laravel documentation](https://laravel.com/docs/5.6/queues) for more information!

### Extending

[](#extending)

If you want to extend or replace one of the core classes with your own implementations, you can override them:

- `CyrildeWit\EloquentViewable\View`
- `CyrildeWit\EloquentViewable\ViewableService`
- `CyrildeWit\EloquentViewable\CrawlerDetector\CrawlerDetectAdapter`

***Note:** Don't forget that all custom classes must implement their original interfaces*

#### Replace `View` model with custom implementation

[](#replace-view-model-with-custom-implementation)

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

#### Replace `ViewableService` service with custom implementation

[](#replace-viewableservice-service-with-custom-implementation)

```
$this->app->singleton(
    \CyrildeWit\EloquentViewable\Contracts\ViewableService::class,
    \App\Services\CustomViewableService::class
);
```

#### Replace `CrawlerDetectAdapter` class with custom implementation

[](#replace-crawlerdetectadapter-class-with-custom-implementation)

```
$this->app->singleton(
    \CyrildeWit\EloquentViewable\Contracts\CrawlerDetector::class,
    \App\Services\CrawlerDetector\CustomAdapter::class
);
```

Recipes
-------

[](#recipes)

### Creating helper methods for frequently used period formats

[](#creating-helper-methods-for-frequently-used-period-formats)

#### App\\Models\\Post

[](#appmodelspost)

```
// ...

public function getViewsSince(DateTime $sinceDateTime)
{
    return $this->getViews(Period::since($sinceDateTime));
}

public function getViewsUpto(DateTime $uptoDateTime)
{
    return $this->getViews(Period::upto($uptoDateTime));
}

public function getViewsBetween(DateTime $sinceDateTime, DateTime $uptoDateTime)
{
    return $this->getViews(Period::create($sinceDateTime, $uptoDateTime));
}

public function getViewsInPastDays(int $days)
{
    return $this->getViews(Period::pastDays($days));
}

// ...
```

#### resources/views/post/show.blade.php

[](#resourcesviewspostshowbladephp)

```

Page views since 2014: {{ $post->getViewsSince(Carbon::create(2014)) }}
Page views upto 2016: {{ $post->getViewsUpto(Carbon::create(2016)) }}
Page views between 2016 - 2018: {{ $post->getViewsBetween(Carbon::create(2016), Carbon::create(2018)) }}

Page views in the past 5 days: {{ $post->getViewsInPastDays(5) }}

```

Upgrading
---------

[](#upgrading)

Please see [UPGRADING](UPGRADING.md) for detailed upgrade guide.

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG-2.0.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Credits
-------

[](#credits)

- [Cyril de Wit](https://github.com/cyrildewit)
- [All Contributors](../../contributors)

License
-------

[](#license)

This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 98.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1747d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/512e4db1d263a5d63a20dec238db25ac78abcc2f0b9c050c02df62be9ea96a4c?d=identicon)[therealedatta](/maintainers/therealedatta)

---

Top Contributors

[![cyrildewit](https://avatars.githubusercontent.com/u/16477999?v=4)](https://github.com/cyrildewit "cyrildewit (455 commits)")[![davidjr82](https://avatars.githubusercontent.com/u/4275886?v=4)](https://github.com/davidjr82 "davidjr82 (4 commits)")[![p3yman](https://avatars.githubusercontent.com/u/2673262?v=4)](https://github.com/p3yman "p3yman (1 commits)")

---

Tags

laraveleloquentcounterviewsvisitshitsviewablevisitablecyrildewit

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/therealedatta-fork-cyrildewit-eloquent-viewable-tags/health.svg)

```
[![Health](https://phpackages.com/badges/therealedatta-fork-cyrildewit-eloquent-viewable-tags/health.svg)](https://phpackages.com/packages/therealedatta-fork-cyrildewit-eloquent-viewable-tags)
```

###  Alternatives

[cyrildewit/eloquent-viewable

Laravel package that allows you to associate views with Eloquent models

8831.1M6](/packages/cyrildewit-eloquent-viewable)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k12.1M99](/packages/laravel-pulse)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[jerome/filterable

Streamline dynamic Eloquent query filtering with seamless API request integration and advanced caching strategies.

19226.1k](/packages/jerome-filterable)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)[ntanduy/cloudflare-d1-database

Easy configuration and setup for D1 Database connections in Laravel.

215.4k](/packages/ntanduy-cloudflare-d1-database)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
