Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Page View Counter in Laravel 5

Tags:

laravel

I'm wondering how you make a page view counter in Laravel 5. Is there any specific package that will help me out with this? I'm basically stuck, as the stable version of Laravel 5 was recently released.

like image 221
djangokillen Avatar asked Feb 22 '15 09:02

djangokillen


1 Answers

There are many ways to accomplish this, but each way has its pros and cons. In this answer, I'm going to show you some different ways to build a pageview counter.

#1 Simple column in a database table

Let's say we are building a blog with posts and we want to keep track of the total pageviews count. What we can do is adding the column views or page_views to our posts database table. This column will store the total number of page views. We can increment this number every time a post is being shown to someone.

Example code:

public function show($id)
{
    $post = \App\Models\Post::find($id); // fetch post from database
    $post->increment('views'); // add a new page view to our `views` column by incrementing it

    return view('posts.show', [
        'post' => $post,
    ]);
}

Then inside your view (blade or php), you can get the column like this;

<div class="panel-footer">
    Views: {{ $post->views }}
</div>

But in this way, we will never know when people exactly viewed the post. It will only possible to get the total count and not the total views of the past 24 hours, 7 days, 14 weeks or from "12-01-2017".

#2 Extra table to store all views

This way is very different from way #1 because each page view will be stored as a record in the table.

Before writing the steps I want to tell you that I created a package called: Eloquent Viewable. It works exactly like #2.

First you need to create a database migration for the views table. This migration should contain the following:

$table->increments('id')->unsigned();
$table->morphs('viewable');
$table->timestamps();

Then we need to create an Eloquent model, so we can fetch the views:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class View extends Model
{
    protected $table = 'views';
    protected $guarded = ['id'];
}

Then add to each model that can be viewed or needs this functionality the following code. In this example, we are providing this functionality to the Post model.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;

class Post extends Model
{
    /**
     * Get the page views associated with the given model.
     *
     * @return \Illuminate\Database\Eloquent\Relations\MorphMany
     */
    public function views()
    {
        return $this->morphMany(
            \App\Models\View::class,
            'viewable'
        );
    }

    /**
     * Get the total number of views.
     *
     * @return int
     */
    public function getViewsCount()
    {
        return $this->views()->count();
    }

    public function getViewsCountSince($sinceDateTime)
    {
        return $this->views()->where('created_at', '>', $sinceDateTime)->count();
    }

    public function getViewsCountUpto($uptoDateTime)
    {
        return $this->views()->where('created_at', '<', $uptoDateTime)->count();
    }
}

Now you can use the following methods to fetch the views counts.

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

// total number of views since the past 24 hours
$post->getViewsCountSince(Carbon::now()->subDay(1));

// total number of views upto 2 months ago
$post->getViewsCountUpto(Carbon::now()->subMonths(2));
like image 92
Cyril de Wit Avatar answered Oct 05 '22 00:10

Cyril de Wit