• Stars
    star
    100
  • Rank 339,431 (Top 7 %)
  • Language
    PHP
  • License
    MIT License
  • Created about 4 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Temporarily and Transparently, tag your eloquent models

Eloquent Temporary Tags

Auto-expiring tags with additional payload data on any eloquent model.





image


Built with ❤️ for every smart laravel developer

Latest Stable Version Build Status Total Downloads StyleCI Quality Score Software License



Installation:

composer require imanghafoori/laravel-temp-tag

Then you can publish and migrate to create the needed tags table

php artisan vendor:publish
php artisan migrate

Sample Application in laravel 8:

https://github.com/imanghafoori1/laravel-tasks

In this Daily Task app, you can mark your tasks as complete,failed,ignored and etc but they rollback back to the default state at the end of the day, so you can re-mark them for tomorrow.

Use cases:

  • You wanna ban a user, but only for a week.

  • You wanna give someone VIP access, but only for a month.

  • Comments approval by admin.

  • You wanna put a product in a slider until the weekend.

  • Storing each user preferences, can be done by attaching a 'settings' tag and the preferences as payload.

  • Storing users likes and dislikes on any model.

  • Scheduling models to be published in the future.

  • Coupon code for specific products on specific periods.

Then you put a temporary tag on them and check to see if the model has the tag.

Tag Payload:

You can also store some additional json data, for example why the user got banned, or who banned the user, or a slug or a translation of the title.

This is done by passing the third argument as an array to the ->tagIt(...) method

Keynotes:

  • Tags can also be permanent.

  • We do not touch your existing tables in migrations.

  • You can put tag on any eloquent model or any other object with getKey and getTable methods on it.


Example:

1- Tag a user until tomorrow

  $user = User::find(1);
  $tomorrow = Carbon::now()->addDay();
  $note = ['reason' => 'You were nasty!']; // You can optionally store additional data in a json column.

  tempTags($user)->tagIt('banned', $tomorrow, $note);

  tempTags($user)->tagIt('banned');  // will never expire

2- After an hour the tag is still active, so:

  $user = User::find(1);
 
  $tagObj = tempTags($user)->getActiveTag('banned');  // <--- Uses cache behind the scenes
  
  if (! is_null($tagObj)) {
    $tagObj->isActive();         // true
    $tagObj->isPermanent();      // false
    $tagObj->title === 'banned'; // true
    $tagObj->payload;            // ['reason' => 'You were nasty!']
    $tagObj->expiresAt();        // Carbon instance
  }

3- After a week, the tag gets expired so:

  $user = User::find(1);
  $tagObj = tempTags($user)->getTag('banned');  // <--- fetches the tag regardless of its expire date.
  
  if (! is_null($tagObj)) {
    $tagObj->isActive();         // false
    $tagObj->isPermanent();      // false
    $tagObj->title === 'banned'; // true
    $tagObj->expiresAt();        // Carbon instance
  }

Getting payload data:

There are 2 ways to get payload data :

You can use getPayload method

  $tagObj->getPayload('reason');       //  'You were nasty!'      
  $tagObj->getPayload();               //  ['reason' => 'You were nasty!'] 
  $tagObj->getPayload('missing_key');  //  null

or You can act like eloquent attributes :

  $tagObj->reason;       //  'You were nasty!'      
  $tagObj->payload;      //  ['reason' => 'You were nasty!'] 
  $tagObj->missing_key;  //  null

Deleting tags:

  $user = User::find(1);
  
  tempTags($user)->unTag('banned');           // single string

  tempTags($user)->unTag('bann*');            // using a wildcard 

  tempTags($user)->unTag(['banned', 'man']);  // an array of tags to delete

  tempTags($user)->deleteExpiredTags();       // all the expired tags, bye bye.

Note: You can also use * wildcard which matcher 0 or more characters (just like % in sql)

Note: These fire "deleting" and "deleted" eloquent events for each one of them.

Expire the tag with title of "banned" right now:

 tempTags($user)->expireNow('banned');  // updates the value of expire_at to now() and deletes from cache

These methods just do what they say:

  $actives = tempTags($user)->getAllActiveTags();  // A collect of "TempTag" model objects.

  $expired = tempTags($user)->getAllExpiredTags();

  $all = tempTags($user)->getAllTags();

Fetch only tagged models:

Let's say you have a slider for your Product model and you want to show only those records which are tagged with 'slider'.

First you have to put Imanghafoori\Tags\Traits\hasTempTags trait on the Product model.

class Product extends Model 
{
  use hasTempTags;
  
  ...
}

Now you can perform these queries:

Product::hasActiveTags('slider')->where(...)->get();

// Only if the tag of model is expired and it has the specified title.
Product::hasExpiredTags('slider')->where(...)->get();

// To fetch regardless of expiration date of tags, only the title matters.
Product::hasTags('slider')->where(...)->get();

Note: If you pass an array of tags it acts like a whereIn(), so if the row has one of tags if will be selected.

If you want to find products which will be active until tomorrow, you can use hasActiveTagsAt, or hasNotActiveTagsAt as illustrated below:

Product::hasActiveTagsAt('slider', now()->addDay())->where(...)->get();

Product::hasNotActiveTagsAt('slider', now()->addDay())->where(...)->get();

Example:

When you want to send a notification to users, just 24 hours before their VIP account gets finished, so that they can charge.

User::hasActiveTag('VIP')
    ->hasNotActiveTagsAt('VIP', now()->addDay())
    ->get();

Absence of tags:

Product::hasNotActiveTags('slider')->where(...)->get();

Product::hasNotExpiredTags('slider')->where(...)->get();

Product::hasNotTags('slider')->where(...)->get();

Example:

When you want your article to be published in the future, go can tag your articles with a custom tag title like: "hidden" And fetch them like this:

$articles = Article::hasNotActiveTags('hidden')->where(...)->get();

So, as long as the 'hidden' tag is active the article does not show on the list and when the tag gets expired the article goes live.


Filtering based on payload:

$product1 = Product::find(1);
$product2 = Product::find(1);

tempTags($product1)->tagIt('status', $tomorrow, ['value' => 'sold_out']);
tempTags($product2)->tagIt('status', $tomorrow, ['value' => 'sold_out']);

// now we have tagged these two rows we can fetch them later on with the below query

...

Product::hasActiveTags('status', ['value' => 'sold_out'])->where(...)->get();

The above example gives you the products with active status tag which have also payload data with the specified key and value.

Note: You can also use * wildcard which matcher 0 or more characters (just like % in sql):

Product::hasActiveTags('stat*', ['value' => 'sold_out'])->where(...)->get();

Advanced Usage:

Each and every has...Tag method also has a twin orHas...Tag so you can put multiple conditions in the query.

Remember that they both should reside in a ->where(function ($q) { beside one another.

Post::where('user_id', 12)->where(function ($q) {
    $q->hasActiveTags('status', ['value' => 'active'])
    ->orHasActiveTags('status', ['value' => 'promoted']);
})->get();

Auto-delete Expired tags:

In order to save disk space and have faster db queries you may want to delete the expired tags.

After you have performed the basic installation you can start using the tag:delete-expired command. In most cases you'll want to schedule this command so you don't have to manually run it everytime you need to delete expired tags.

// app/Console/Kernel.php

protected function schedule(Schedule $schedule)
{
    // Will run:  php artisan  tag:delete-expired
    $schedule->command( 'tag:delete-expired' )->everyDay();
}

🙋 Contributing:

If you find an issue or have a better way to do something, feel free to open an issue, or a pull request.

Your Stars Make Us Do More

As always if you found this package useful, and you want to encourage us to maintain and work on it, just press the star button to declare your willingness.


More from the author:

Laravel Microscope

💎 It automatically find bugs in your laravel app

Laravel HeyMan

💎 It allows you to write expressive code to authorize, validate, and authenticate.


This package is originally inspired by the cybercog/laravel-ban package.



It's not that I'm so smart, it's just that I stay with problems longer.


"Albert Einstein"

More Repositories

1

laravel-microscope

Fearless refactoring, it does a lot of smart checks to find certain errors.
PHP
1,307
star
2

laravel-widgetize

A minimal package to help you make your laravel application cleaner and faster.
PHP
902
star
3

laravel-heyman

Declarative style of authorization and validation in laravel.
PHP
880
star
4

laravel-MasterPass

Helps you securely setup a master password and login into user accounts with it.
PHP
354
star
5

laravel-terminator

A package to help you clean up your controllers in laravel
PHP
246
star
6

laravel-video

A laravel package to stream video content.
PHP
232
star
7

laravel-anypass

A minimal package that helps you login with any password on local environments
PHP
211
star
8

eloquent-relativity

Allows you to decouple your eloquent models from one another.
PHP
147
star
9

laravel-decorator

Easily decorate your method calls with laravel-decorator package
PHP
129
star
10

eloquent-mockery

Mock your eloquent queries without the repository pattern
PHP
123
star
11

laravel-middlewarize

Use middleware to decorate method calls within your application code.
PHP
105
star
12

laravel-nullable

Functional programming paradigms in laravel to avoid run-time errors.
PHP
102
star
13

laravel-smart-facades

Strategy design pattern in laravel, the easiest way.
PHP
87
star
14

laravel-password-history

Keep a password history of your users to prevent them from reusing the same password.
PHP
64
star
15

iranian-laravel-contributors

The list of people from Iran who have contributed to the laravel framework
40
star
16

laravel-tokenized-login

Two factor authentication in Laravel
PHP
36
star
17

eloquent-history

PHP
31
star
18

smart-realtime-facades

PHP
30
star
19

php-smart-search-replace

Smart search/replace functionality for PHP code
PHP
27
star
20

gilded_rose

Based on a tutorial for code refactoring
PHP
25
star
21

why_github_is_not_open_source

Why github.com is NOT open-source???
25
star
22

laravel-makesure

Readable syntax to write tests in laravel
PHP
21
star
23

eloquent-rating

5 star rating for eloquent models
PHP
18
star
24

laravel-file-cache-cleaner

Delete the obsolete cache files in the storage directory
PHP
15
star
25

php_token_analyzer

PHP
11
star
26

laravel-db-freeze

A package that allows you to bypass any insert, edit, delete into your database in demo mode through .env variables
10
star
27

laravel-anytoken

A minimal development package that helps you fake any api token as a valid one during development
10
star
28

composer-json

A utility class for read composer.json data and use it in PHP
PHP
9
star
29

crudbooster-statistics

Statistics module for Crudbooster CMS
HTML
8
star
30

imanghafoori1

8
star
31

laravel-microscope-ui

8
star
32

laravel-tik8

Simple modular ticketing system by laravel
8
star
33

crudbooster-logs

A plug-in for CrudBooster CMS to add log functionality
PHP
8
star
34

chat

node chat application
HTML
7
star
35

crudbooster-notifications

Adds notification functionality to crudbooster
PHP
7
star
36

laravel-nice-middlewares

This is a plug-in for laravel-middlewarize package.
PHP
6
star
37

questionist

Advanced event/listener system
PHP
6
star
38

abstract_php_filesystem

PHP
3
star
39

example_query

PHP
2
star
40

test-bin

1
star
41

laravel-endpoints

Define your endpoints as classes
1
star
42

git_toturial

1
star