diff --git a/README.md b/README.md index 0fb4f14..6c63845 100644 --- a/README.md +++ b/README.md @@ -1 +1,152 @@ -# wip +

+ Laravisit Logo +

+

+ +[![The Latest Version on Packagist](https://img.shields.io/packagist/v/coderflexx/laravisit.svg?style=flat-square)](https://packagist.org/packages/coderflexx/laravisit) +[![GitHub Tests Action Status](https://img.shields.io/github/workflow/status/coderflexx/laravisit/run-tests?label=tests)](https://github.com/coderflexx/laravisit/actions?query=workflow%3Arun-tests+branch%3Amain) +[![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/coderflexx/laravisit/Check%20&%20fix%20styling?label=code%20style)](https://github.com/coderflexx/laravisit/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain) + +A clean way to track your pages & understand your user's behavior + +## Installation + +You can install the package via composer: + +```bash +composer require coderflexx/laravisit +``` + +You can publish the config file with: + +```bash +vendor:publish --provider="Coderflex\\Laravisit\\LaravisitServiceProvider" +``` + +then, run database migration +```bash +php artisan migrate +``` + +This is the contents of the published config file: +```php +return [ + /* + |-------------------------------------------------------------------------- + | User Namespace + |-------------------------------------------------------------------------- + | + | This value informs Laravist which namespace you will be + | selecting to get the user model instance + | If this value equals to null, "\Coderflex\Laravisit\Models\User" will be used + | by default. + | + */ + 'user_namespace' => "\Coderflex\Laravisit\Models\User", +]; +``` + + +## Usage + +### Use `HasVisits` Trait + +The first thing you need to do is, to use `HasVisits` trait + +```php +namespace App\Models\Post; + +use Coderflex\Laravisit\Concerns\HasVisits; +use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Model; + +class Post extends Model +{ + ... + use HasFactory; + use HasVisits; + ... +} +``` +After this step, you are reading to go, and when you need to track a page, do it like this: + +```php +$post->visit(); +``` + +You can chain methods to the `visit` method. Here is a list of the available methods: + +| METHOD | SYNTAX | DESCRIPTION | EXAMPLE | +| ----------- | ----------- | ----------- | ----------- | +| `withIp()` | string `$ip = null` | Set an Ip address (default `request()->ip()`) | `$post->visit()->withIp()` | +|`withData()` | array `$data` | Set custom data | `$post->visit()->withData(['region' => 'USA'])` | +| `withUser()` | Model `$user = null` | Set a user model (default `auth()->user()`) | `$user->visit()->withUser()` | + +--- + +By default, you will have unique visits __each day__ using `dailyInterval()` method. Meaning, when the users access the page multiple times in the day time frame, you will see just `one record` related to them. + +If you want to log users access to page with different __timeframes__, here are a bunch of useful methods: + +| METHOD | SYNTAX | DESCRIPTION | EXAMPLE | +| ----------- | ----------- | ----------- | ----------- | +| `hourlyInterval()` | `void` | Log visits each hour | `$post->visit()->hourlyIntervals()->withIp();` | +| `dailylyInterval()` | `void` | Log visits each daily | `$post->visit()->dailylyIntervals()->withIp();` | +| `weeklyInterval()` | `void` | Log visits each week | `$post->visit()->weeklyIntervals()->withIp();` | +| `monthlyInterval()` | `void` | Log visits each month | `$post->visit()->monthlyIntervals()->withIp();` | +| `yearlyInterval()` | `void` | Log visits each year | `$post->visit()->yearlyIntervals()->withIp();` | +| `customInterval()` | mixed `$interval` | Log visits within a custom interval | `$post->visit()->customInterval( now()->subYear() )->withIp();` | + +### Get The Records With Popular Time Frames +After the visits get logged, you can retrieve the data by the following method: + +| METHOD | SYNTAX | DESCRIPTION | EXAMPLE | +| ----------- | ----------- | ----------- | ----------- | +| `withTotalVisitCount()` | `void` | get total visit count | `Post::withTotalVisitCount()->first()->visit_count_total` | +| `popularAllTime()` | `void` | get popular visits all time | `Post::popularAllTime()->get()` | +| `popularLastDays()` | int `$days` | get popular visits last given days | `Post::popularLastDays(10)->get()` | +| `popularThisWeek()` | `void` | get popular visits this week | `Post::popularThisWeek()->get()` | +| `popularLastWeek()` | `void` | get popular visits last week | `Post::popularLastWeek()->get()` | +| `popularThisMonth()` | `void` | get popular visits this month | `Post::popularThisMonth()->get()` | +| `popularLastMonth()` | `void` | get popular visits last month | `Post::popularLastMonth()->get()` | +| `popularThisYear()` | `void` | get popular visits this year | `Post::popularThisYear()->get()` | +| `popularLastYear()` | `void` | get popular visits last year | `Post::popularLastYear()->get()` | +| `popularBetween()` | Carbon `$from`, Carbon `$to` | get popular visits between custom two dates | `Post::popularBetween(Carbon::createFromDate(2019, 1, 9), Carbon::createFromDat(2022, 1, 3))->get();` | + +## Visit Presenter +This package is coming with helpful decorate model properties, and it uses [Laravel Presenter](https://github.com/coderflexx/laravel-presenter) package under the hood. + +| METHOD | SYNTAX | DESCRIPTION | EXAMPLE | +| ----------- | ----------- | ----------- | ----------- | +| `ip()` | `void` | Get the associated IP from the model instance | `$post->visits->first()->present()->id`| +| `user()` | `void` | Get the associated User from the model instance | `$post->visits->first()->present()->user->name`| + +## Testing + +```bash +composer test +``` + +## Changelog + +Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. + +## Contributing + +Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details. + +## Security Vulnerabilities + +Please review [our security policy](../../security/policy) on how to report security vulnerabilities. + +## Inspiration +- [Codecourse Laravel Model Popularity](https://codecourse.com/courses/laravel-model-popularity) + +## Credits + +- [Oussama Sid](https://github.com/ousid) +- [All Contributors](../../contributors) + +## License + +The MIT License (MIT). Please see [License File](LICENSE.md) for more information. diff --git a/composer.json b/composer.json index f6838a5..5838e28 100644 --- a/composer.json +++ b/composer.json @@ -55,10 +55,7 @@ "laravel": { "providers": [ "Coderflex\\Laravisit\\LaravisitServiceProvider" - ], - "aliases": { - "Laravisit": "Coderflex\\Laravisit\\Facades\\Laravisit" - } + ] } }, "minimum-stability": "dev", diff --git a/config/laravisit.php b/config/laravisit.php index 8866937..1e4c9d7 100644 --- a/config/laravisit.php +++ b/config/laravisit.php @@ -3,13 +3,14 @@ return [ /* |-------------------------------------------------------------------------- - | Home Path + | User Namespace |-------------------------------------------------------------------------- | - | Here you may configure the path where users will get redirected during - | authentication or password reset when the operations are successful - | and the user is authenticated. You are free to change this value. + | This value informs Laravist which namespace you will be + | selecting to get the user model instance + | If this value equals to null, "\Coderflex\Laravisit\Models\User" will be used + | by default. | */ - 'user_namespace' => "\Coderflex\Laravisit\Tests\Models\User", + 'user_namespace' => "\Coderflex\Laravisit\Models\User", ]; diff --git a/src/Concerns/FilterByPopularityTimeFrame.php b/src/Concerns/FilterByPopularityTimeFrame.php index cde3a5e..a34e522 100644 --- a/src/Concerns/FilterByPopularityTimeFrame.php +++ b/src/Concerns/FilterByPopularityTimeFrame.php @@ -34,6 +34,8 @@ public function scopePopularAllTime(Builder $builder): Builder ->orderBy('visit_count_total', 'desc'); } + // TODO: add popular today method with tests and documentation + /** * Get the popular visits last given days * diff --git a/src/Concerns/SetsPendingIntervals.php b/src/Concerns/SetsPendingIntervals.php index 5583b86..e22e6f7 100644 --- a/src/Concerns/SetsPendingIntervals.php +++ b/src/Concerns/SetsPendingIntervals.php @@ -54,10 +54,10 @@ public function __call($name, $arguments): mixed /** * Set Custom Interval * - * @param DateTime $interval + * @param mixed $interval * @return self */ - public function customInterval($interval): self + public function customInterval(mixed $interval): self { $this->interval = $interval instanceof Carbon ? $interval diff --git a/src/Models/User.php b/src/Models/User.php new file mode 100644 index 0000000..d1f97bb --- /dev/null +++ b/src/Models/User.php @@ -0,0 +1,45 @@ + + */ + protected $fillable = [ + 'name', + 'email', + 'password', + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var array + */ + protected $hidden = [ + 'password', + 'remember_token', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'email_verified_at' => 'datetime', + ]; +} + diff --git a/src/PendingVisit.php b/src/PendingVisit.php index 90c46d9..23f8c11 100644 --- a/src/PendingVisit.php +++ b/src/PendingVisit.php @@ -36,7 +36,7 @@ public function withIP(string $ip = null): self } /** - * Set IP attribute + * Set Custom Data attribute * * @param array $data * @return $this @@ -55,10 +55,10 @@ public function withData(array $data): self /** * Set User attribute * - * @param User $user + * @param Model $user * @return $this */ - public function withUser($user = null): self + public function withUser(Model $user = null): self { $this->attributes['user_id'] = $user?->id ?? auth()->id(); diff --git a/src/Presenters/VisitPresenter.php b/src/Presenters/VisitPresenter.php index 9c8188f..8e48204 100644 --- a/src/Presenters/VisitPresenter.php +++ b/src/Presenters/VisitPresenter.php @@ -8,7 +8,7 @@ class VisitPresenter extends Presenter { /** - * Get the associated IP of from the model instance + * Get the associated IP from the model instance * * @return string */ @@ -25,9 +25,14 @@ public function ip(): string public function user(): Model { $userId = $this->model->data['user_id']; + $userNamespace = config('laravisit.user_namespace'); - $user = config('laravisit.user_namespace'); + $user = is_null($userNamespace) || empty($userNamespace) + ? '\Coderflex\Laravisit\Models\User' + :$userNamespace; return (new $user())->find($userId); } + + // TODO: get total visit count presenter method with tests and documentation } diff --git a/tests/Feature/Visits/PopularityTest.php b/tests/Feature/Visits/PopularityTest.php index bb5eea1..bd4f4b9 100644 --- a/tests/Feature/Visits/PopularityTest.php +++ b/tests/Feature/Visits/PopularityTest.php @@ -48,7 +48,7 @@ $popularPosts = Post::popularBetween( Carbon::createFromDate(2020, 10, 9), - Carbon::createFromDate(2020, 10, 11), + Carbon::createFromDate(2020, 10, 11) )->get(); expect($popularPosts->count())->toBe(1); diff --git a/tests/Unit/Visits/VisitsTest.php b/tests/Unit/Visits/VisitsTest.php deleted file mode 100644 index b3d9bbc..0000000 --- a/tests/Unit/Visits/VisitsTest.php +++ /dev/null @@ -1 +0,0 @@ -