Merge branch '1-view-count' into 'master'
Resolve "View Count" Closes #1 See merge request daniel/personal-website!2
This commit is contained in:
commit
81356ac945
@ -20,6 +20,8 @@ FILESYSTEM_DRIVER=local
|
|||||||
QUEUE_CONNECTION=sync
|
QUEUE_CONNECTION=sync
|
||||||
SESSION_DRIVER=file
|
SESSION_DRIVER=file
|
||||||
SESSION_LIFETIME=120
|
SESSION_LIFETIME=120
|
||||||
|
# Only required if using a custom port on APP_URL
|
||||||
|
# SANCTUM_STATEFUL_DOMAINS=localhost:8000
|
||||||
|
|
||||||
MEMCACHED_HOST=127.0.0.1
|
MEMCACHED_HOST=127.0.0.1
|
||||||
|
|
||||||
|
|||||||
@ -61,7 +61,7 @@ class BlogArticleController extends Controller
|
|||||||
public function popular()
|
public function popular()
|
||||||
{
|
{
|
||||||
$data = BlogArticle::select()
|
$data = BlogArticle::select()
|
||||||
->orderBy('views', 'desc')
|
->orderByUniqueViews('desc')
|
||||||
->orderBy('date', 'desc')
|
->orderBy('date', 'desc')
|
||||||
->where('published', true)
|
->where('published', true)
|
||||||
->limit(5)
|
->limit(5)
|
||||||
@ -89,14 +89,23 @@ class BlogArticleController extends Controller
|
|||||||
* @param \App\Models\BlogArticle $blogArticle
|
* @param \App\Models\BlogArticle $blogArticle
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return \Illuminate\Http\JsonResponse
|
||||||
*/
|
*/
|
||||||
public function show(BlogArticle $blogArticle)
|
public function show(int $id)
|
||||||
{
|
{
|
||||||
if (!$this->authService->isAuthenticated() && !$blogArticle->published) {
|
$blogArticle = BlogArticle::withCount('views')->find($id);
|
||||||
|
|
||||||
|
if ($blogArticle === null) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
$blogArticle->views += 1;
|
if (!$this->authService->isAuthenticated()) {
|
||||||
$blogArticle->save();
|
if (!$blogArticle->published) {
|
||||||
|
abort(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
views($blogArticle)
|
||||||
|
->cooldown(now()->addHour())
|
||||||
|
->record();
|
||||||
|
}
|
||||||
|
|
||||||
return response()->json($blogArticle);
|
return response()->json($blogArticle);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,7 @@ class Kernel extends HttpKernel
|
|||||||
],
|
],
|
||||||
|
|
||||||
'api' => [
|
'api' => [
|
||||||
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||||
'throttle:api',
|
'throttle:api',
|
||||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
],
|
],
|
||||||
|
|||||||
@ -2,12 +2,15 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use CyrildeWit\EloquentViewable\Contracts\Viewable;
|
||||||
|
use CyrildeWit\EloquentViewable\InteractsWithViews;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class BlogArticle extends Model
|
class BlogArticle extends Model implements Viewable
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
use InteractsWithViews;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'title',
|
'title',
|
||||||
@ -15,7 +18,6 @@ class BlogArticle extends Model
|
|||||||
'date',
|
'date',
|
||||||
'summary',
|
'summary',
|
||||||
'content',
|
'content',
|
||||||
'views',
|
|
||||||
'published'
|
'published'
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -24,7 +26,8 @@ class BlogArticle extends Model
|
|||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'date' => 'datetime',
|
'date' => 'datetime',
|
||||||
'views' => 'integer',
|
|
||||||
'published' => 'boolean',
|
'published' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected $removeViewsOnDelete = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.3|^8.0",
|
"php": "^7.3|^8.0",
|
||||||
|
"cyrildewit/eloquent-viewable": "^6.0",
|
||||||
"doctrine/dbal": "^3.1",
|
"doctrine/dbal": "^3.1",
|
||||||
"fruitcake/laravel-cors": "^2.0",
|
"fruitcake/laravel-cors": "^2.0",
|
||||||
"guzzlehttp/guzzle": "^7.0.1",
|
"guzzlehttp/guzzle": "^7.0.1",
|
||||||
|
|||||||
131
composer.lock
generated
131
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "2e27ad4aeb64c5f5afd5be0288a4a9e2",
|
"content-hash": "5ceb5b6e26fc35fd4fd26e6d152d3b11",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "asm89/stack-cors",
|
"name": "asm89/stack-cors",
|
||||||
@ -195,6 +195,83 @@
|
|||||||
],
|
],
|
||||||
"time": "2021-08-17T13:49:14+00:00"
|
"time": "2021-08-17T13:49:14+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "cyrildewit/eloquent-viewable",
|
||||||
|
"version": "v6.0.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/cyrildewit/eloquent-viewable.git",
|
||||||
|
"reference": "699294489e397c18a59ff9fafadde8154be85c02"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/cyrildewit/eloquent-viewable/zipball/699294489e397c18a59ff9fafadde8154be85c02",
|
||||||
|
"reference": "699294489e397c18a59ff9fafadde8154be85c02",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"illuminate/cache": "^6.0|^7.0|^8.0",
|
||||||
|
"illuminate/contracts": "^6.0|^7.0|^8.0",
|
||||||
|
"illuminate/cookie": "^6.0|^7.0|^8.0",
|
||||||
|
"illuminate/database": "^6.0|^7.0|^8.0",
|
||||||
|
"illuminate/http": "^6.0|^7.0|^8.0",
|
||||||
|
"illuminate/support": "^6.0|^7.0|^8.0",
|
||||||
|
"jaybizzle/crawler-detect": "^1.0",
|
||||||
|
"nesbot/carbon": "^2.0",
|
||||||
|
"php": "^7.4|^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"illuminate/config": "^6.0|^7.0|^8.0",
|
||||||
|
"mockery/mockery": "^1.2.4",
|
||||||
|
"orchestra/testbench": "^4.9.1|^5.9.1|^6.6.1",
|
||||||
|
"phpunit/phpunit": "^9.3.3"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"CyrildeWit\\EloquentViewable\\EloquentViewableServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"CyrildeWit\\EloquentViewable\\": "src/"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/helpers.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Cyril de Wit",
|
||||||
|
"email": "info@cyrildewit.nl",
|
||||||
|
"homepage": "http://cyrildewit.nl",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Laravel package that allows you to associate views with Eloquent models",
|
||||||
|
"homepage": "https://github.com/cyrildewit/eloquent-viewable",
|
||||||
|
"keywords": [
|
||||||
|
"counter",
|
||||||
|
"eloquent",
|
||||||
|
"hits",
|
||||||
|
"laravel",
|
||||||
|
"viewable",
|
||||||
|
"views",
|
||||||
|
"visitable",
|
||||||
|
"visits"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/cyrildewit/eloquent-viewable/issues",
|
||||||
|
"source": "https://github.com/cyrildewit/eloquent-viewable/tree/v6.0.2"
|
||||||
|
},
|
||||||
|
"time": "2021-01-02T15:47:17+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dflydev/dot-access-data",
|
"name": "dflydev/dot-access-data",
|
||||||
"version": "v3.0.1",
|
"version": "v3.0.1",
|
||||||
@ -1295,6 +1372,58 @@
|
|||||||
},
|
},
|
||||||
"time": "2021-06-30T20:03:07+00:00"
|
"time": "2021-06-30T20:03:07+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "jaybizzle/crawler-detect",
|
||||||
|
"version": "v1.2.106",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/JayBizzle/Crawler-Detect.git",
|
||||||
|
"reference": "78bf6792cbf9c569dc0bf2465481978fd2ed0de9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/78bf6792cbf9c569dc0bf2465481978fd2ed0de9",
|
||||||
|
"reference": "78bf6792cbf9c569dc0bf2465481978fd2ed0de9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.8|^5.5|^6.5|^9.4"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Jaybizzle\\CrawlerDetect\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Mark Beech",
|
||||||
|
"email": "m@rkbee.ch",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "CrawlerDetect is a PHP class for detecting bots/crawlers/spiders via the user agent",
|
||||||
|
"homepage": "https://github.com/JayBizzle/Crawler-Detect/",
|
||||||
|
"keywords": [
|
||||||
|
"crawler",
|
||||||
|
"crawler detect",
|
||||||
|
"crawler detector",
|
||||||
|
"crawlerdetect",
|
||||||
|
"php crawler detect"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/JayBizzle/Crawler-Detect/issues",
|
||||||
|
"source": "https://github.com/JayBizzle/Crawler-Detect/tree/v1.2.106"
|
||||||
|
},
|
||||||
|
"time": "2021-05-24T20:30:32+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/framework",
|
"name": "laravel/framework",
|
||||||
"version": "v8.58.0",
|
"version": "v8.58.0",
|
||||||
|
|||||||
107
config/eloquent-viewable.php
Normal file
107
config/eloquent-viewable.php
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Eloquent Models
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
'models' => [
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here you can configure the default `View` model.
|
||||||
|
*/
|
||||||
|
'view' => [
|
||||||
|
|
||||||
|
'table_name' => 'views',
|
||||||
|
'connection' => env('DB_CONNECTION', 'mysql'),
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Cache Configuration
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
'cache' => [
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Everthing will be stored under the following key.
|
||||||
|
*/
|
||||||
|
'key' => 'cyrildewit.eloquent-viewable.cache',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here you may define the cache store that should be used.
|
||||||
|
*/
|
||||||
|
'store' => env('CACHE_DRIVER', 'file'),
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Cooldown Configuration
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
'cooldown' => [
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Everthing will be stored under the following key in the session.
|
||||||
|
*/
|
||||||
|
'key' => 'cyrildewit.eloquent-viewable.cooldowns',
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Ignore Bots
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| If you want to ignore bots, you can specify that here. The default
|
||||||
|
| service that determines if a visitor is a crawler is a package
|
||||||
|
| by JayBizzle called CrawlerDetect.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
'ignore_bots' => true,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Do Not Track Header
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| If you want to honor the DNT header, you can specify that here. We won't
|
||||||
|
| record views from visitors with the Do Not Track header.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
'honor_dnt' => true,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Cookies
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This package binds visitors to views using a cookie. If you want to
|
||||||
|
| give this cookie a custom name, you can specify that here.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'visitor_cookie_key' => 'eloquent_viewable',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Ignore IP Addresses
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Ignore views of the following IP addresses.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'ignored_ip_addresses' => [
|
||||||
|
|
||||||
|
// '127.0.0.1',
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
||||||
62
database/migrations/2021_09_04_082939_create_views_table.php
Normal file
62
database/migrations/2021_09_04_082939_create_views_table.php
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreateViewsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The database schema.
|
||||||
|
*
|
||||||
|
* @var \Illuminate\Support\Facades\Schema
|
||||||
|
*/
|
||||||
|
protected $schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The table name.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new migration instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->schema = Schema::connection(
|
||||||
|
config('eloquent-viewable.models.view.connection')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->table = config('eloquent-viewable.models.view.table_name');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$this->schema->create($this->table, function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->morphs('viewable');
|
||||||
|
$table->text('visitor')->nullable();
|
||||||
|
$table->string('collection')->nullable();
|
||||||
|
$table->timestamp('viewed_at')->useCurrent();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->schema->dropIfExists($this->table);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class RemoveViewsFromBlogArticles extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('blog_articles', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('views');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('blog_articles', function (Blueprint $table) {
|
||||||
|
$table->integer('views')->default(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user