Code Monkey home page Code Monkey logo

laravel-meta's Introduction

Laravel Meta

a laravel package for working with meta !

Package Image

Zoha - laravel-meta stars - laravel-meta forks - laravel-meta GitHub tag License

Page Contents

  1. Introduction
  2. Features
  3. Installation
  4. Basic Methods
  5. Clauses
  6. Other Methods And Features
  7. License
  8. Contributing

Introduction

gif-file

Sometimes our models in laravel needs a lot of information that should be stored in the database. For example, Suppose you want to create a blog and add a model for posts on this blog. The most important information that this model will need is its title and content. But this model may also have more information, Such as the number of likes, download links, thumbnails, views, and more. When the amount of this information is high, We need to create more columns for the model table, Which if there are too many, Will be difficult. Additionally, Each of these posts may have their own unique information that the rest of the posts do not need. In such cases, This package will help. If we want to explain this package simply: Laravel Meta allows you to store information for each of your models and easily access them without having to create new columns for this information in the database tables. If you still do not notice it, Just look at the examples below.

Features

  • It is easy to store and receive meta for each model
  • An alternative to creating many columns in the database table
  • Minimum number of queries and complete optimization
  • Ability to filter database records by meta

Installation

First , Require this package with composer

 $ composer require zoha/laravel-meta

If you Use Laravel <= 5.4 add the ServiceProvider and Alias in config/app.php

'providers' => [
    ...
    Zoha\Meta\MetaServiceProvider::class,
    ...
]
'aliases' => [
    ...
    'Meta' => Zoha\Meta\Facades\MetaFacade::class,
    ...
]

And execute migrate command to migrate meta table

 $ php artisan migrate

And then to add meta functionality to each of your models, You just need to extends it from MetableModel instead of the Model.

use Zoha\MetableModel;

class Post extends MetableModel
{
    ...
}

Or you can use Metable trait instead :

use Zoha\Metable;

class Post extends Model
{
    use Metable;
    ...
}
Optional Section

You can publish meta config file using this command :

 $ php artisan vendor:publish --provider="Zoha\Meta\MetaServiceProvider" --tag=config

In this file you can change default meta table ( default: meta ) Or you can customize meta table for a specific model

That's it! Now you can use all of the Laravel meta features

In all of the examples below, we assume that the $post is set to Post::first() which Post model is an example model

Basic Methods

Create New Meta

For create a meta you can use createMeta on Model :

$post->createMeta('key' , 'value');

Or you can create multiple meta like this :

$post->createMeta([
    'key1' => 'value1',
    'key2' => 'value2'
]);

@return : createMeta method returns true if the meta creation is performed successfully and false otherwise

addMeta method is alias of createMeta method

Update Meta

For update a meta you can use updateMeta on Model :

$post->updateMeta('key' , 'new value');

Or you can update multiple meta like this :

$post->updateMeta([
    'key1' => 'new value 1',
    'key2' => 'new value 2'
]);

@return : If the update was successful updateMeta return true . but if meta already not exists or updating was faild false will be returned

Create Or Update Meta

For create or update meta use setMeta method this method will update meta or create a new one if not exists yet

$post->setMeta('key' , 'value'); // create meta
$post->setMeta('key' , 'new value'); // update meta

Or you can set multiple meta like this

$post->setMeta([
    'key1' => 'value 1',
    'key2' => 'value 2'
]);

@return : setMeta returns true if it is successful. Otherwise it will return false

Or instead of this method, You can set meta using meta property like this :

$post->meta->key1 = 'value';
$post->meta->key2 = 'value2';
$post->meta->save();

Get Meta

getMeta method will return meta value :

//return meta value or null if meta not exists
$post->getMeta('key');

// return value or 'default value ' if not exists or value is null
$post->getMeta('key' , 'default value') ;

Also you can get meta values using meta property :

$post->meta->key; // return meta value

Get Metas

getMetas method will return all metas as a collection :

// return a collection of all metas for this model
// no meta yet ? -> empty collection
$post->getMetas() ;

Delete Meta

For delete meta use deleteMeta method

$post->deleteMeta(); // delete all meta of this model

$post->deleteMeta('key'); // delete a specific meta

Or you can use unsetMeta method instead . both of methods are the same. truncateMeta also delete all meta of specific model :

$post->truncateMeta(); // delete all model meta

Check Meta Exists Or Not

You can use hasMeta method if you want to check there is a particular meta or not ( if meta exists but value equals to null false will be returned )

$post->hasMeta(); // return true if this model has at least one meta
$post->hasMeta('key'); // return true or false

The second argument specifies whether or not to accept null values . If you pass true for second argument , and meta exists even if value equals to null true will be returned

$post->setMeta('key' , null); // set key to null
$post->hasMeta('key'); // return false
$post->hasMeta('key' , true); // return true

If you want to specify that a particular post has a specific meta, even if its value is null , use the existsMeta method.

$post->setMeta('key' , null); // set key to null
$post->existsMeta('key'); // return true

Increase Meta

You can simply increase meta value using increaseMeta method. Note that incrementing a float value will not increment the decimal unless specified.

$post->setMeta('key' , 3);
$post->increaseMeta('key'); // meta value will change to 4

$post->setMeta('key' , 3.5);
$post->increaseMeta('key'); // meta value will change to 4.5

$post->setMeta('key' , 3.5);
$post->increaseMeta('key' , .1); // meta value will change to 3.6

$post->setMeta('key2' , 'not integer value');
$post->increaseMeta('key2'); // meta value will not change

You can pass second argument for detemine increase step

$post->setMeta('key' , 3);
$post->increaseMeta('key',3); // meta value will change to 6

Decrease Meta

You can simply decrease meta value using decreaseMeta method. Note that decrementing a float value will not decrement the decimal value unless specified.

$post->setMeta('key' , 3);
$post->decreaseMeta('key'); // meta value will change to 2

$post->setMeta('key' , 3.5);
$post->decreaseMeta('key'); // meta value will change to 2.5

$post->setMeta('key' , 3.5);
$post->decreaseMeta('key', .1); // meta value will change to 3.4

$post->setMeta('key2' , 'not integer value');
$post->decreaseMeta('key2'); // meta value will not change

And you can pass second argument for detemine decrease step

$post->setMeta('key' , 3);
$post->decreaseMeta('key',3); // meta value will change to 0

Clauses

Where Meta Clause

Filter items by meta value :

$result = Post::whereMeta('key','value');
// you can use operator :
$result = Post::whereMeta('key', '>' , 100);

// you can use multiple whereMeta Clause
$result = Post::whereMeta('key', '>' , 100)
                            ->whereMeta('key' , '<' , 200);
//orWhereMeta clause
$result = Post::whereMeta('key', '>' , 100)
                            ->orWhereMeta('key' , '<' , 50);
//branched clauses
$result = Post::where(function($query){
    $query->where(function($query){
        $query->whereMeta('key1' , 'value1');
        $query->orWhereMeta('key1' , 'value2');
    });
    $query->whereMeta('key2' , 'like' , '%value%');
    $query->WhereMeta('key3' , '>' , 100);
});

You can also pass a array for filter result :

// all of below conditions will converted to 'AND'
$result = Post::whereMeta([
    'key1' => 'value1',
    [ 'key2' , '!=' , 'value2' ],
    [ 'key3' , 'value3' ]
]);

You can aslso use orWhere for mulitple or where clause :

$result = Post::orWhereMeta([
    'key1' => 'value1',
    [ 'key2' , '!=' , 'value2' ],
    [ 'key3' , 'value3' ]
]);

You can use branched filters for all meta clauses

Where Meta In Clause

whereMetaIn and whereMetaNotIn clauses :

$result = Post::whereMetaIn('key', ['value1' , 'value2']);
$result = Post::whereMetaNotIn('key', ['value1' , 'value2']);

// multiple clauses
$result = Post::whereMetaIn('key', [1,2])
                            ->whereMetaIn('key2' , [1,2]);

// 'orWhere' clauses
$result = Post::whereMetaNotIn('key', [1,2,3])
                            ->orWhereMetaIn('key2', [1,2])
                            ->orWhereMetaNotIn('key3', [1,2]);

Where Meta Between Clause

whereMetaBetween and whereMetaNotBetween clauses :

$result = Post::whereMetaBetween('key', [0,100]);
$result = Post::whereMetaNotBetween('key', [0,100]);

// multiple clauses
$result = Post::whereMetaBetween('key', [100,200])
                            ->whereMetaBetween('key2' , [100,200]);

// 'orWhere' clauses
$result = Post::whereMetaNotBetween('key', [1000,8000])
                            ->orWhereMetaBetween('key2', [1,5])
                            ->orWhereMetaNotBetween('key3', [0,100]);

Where Meta Null Clause

whereMetaNull and whereMetaNotNull clauses :

$result = Post::whereMetaNull('key');
$result = Post::whereMetaNotNull('key');

// multiple clauses
$result = Post::whereMetaNull('key')
                            ->whereMetaNull('key2');

// 'orWhere' clauses
$result = Post::whereMetaNotNull('key')
                            ->orWhereMetaNull('key2')
                            ->orWhereMetaNotNull('key3');

Where Meta Has Clause

whereMetaHas and whereMetaDoesntHave clauses :

//filter records that has at least one meta
$result = Post::whereMetaHas();

$result = Post::whereMetaHas('key');
$result = Post::whereMetaHas('key' , true); //count null values

$result = Post::whereMetaDoesntHave('key');
$result = Post::whereMetaDoesntHave('key' , true); //count null values

// multiple clauses
$result = Post::whereMetaHas('key')
                            ->whereMetaDoesntHave('key2');

// 'orWhere' clauses
$result = Post::whereMetaDoesntHave('key')
                            ->orWhereMetaHas('key2')
                            ->orWhereMetaDoesntHave('key3');

Order By Meta

You Can Sort Database Results Using orderByMeta clause :

Post::orderByMeta('price')->get();

Post::orderByMeta('price' , 'desc')->get();

Post::orderByMeta('price')->orderByMeta('likes' , 'desc')->get();

Eager Loading

If you call $post->getMeta('key') for the first time all of this model meta will be loaded ( once ) and if you try to get another meta from this model another query will not be executed and meta value will loaded from previous query. But if you try to get meta in another model, Another query will be executed for new model . If you want get all meta of all models in one query you can use eager loading of meta . you just need to call withMeta scope like this :

$posts = Post::withMeta()->get(); // will return all posts results with their meta values

Note that with('meta') will not work

Other Methods And Features

Notes

  • by default all collections , arrrays and json values will convert to collection when you try to get them.
  • all [] , "{}" , "[]" and null values will be considered null.
  • If one of the items in the metable model is deleted, All the meta related to that item will be deleted too.

Data Type

All of setMeta , getMeta , updateMeta And createMeta methods accept a third argument that determine meta data type . there are some examples of this feature :

Available data types : string , integer , float , null , collection , json array , boolean.

In setMeta method

$post->setMeta('key' , '123' , 'integer');
$post->meta->key; // 123 ( integer )

$post->setMeta('key' , '123.45' , 'integer');
$post->meta->key; // 123 ( integer - decimal dropped)

$post->setMeta('key' , '123.45' , 'float');
$post->meta->key; // 123.45 ( float )
//----------------------------------
$post->setMeta('key' , [1,2,3] , 'json');
$post->meta->key; // "[1,2,3]" ( string - json )
//----------------------------------
$post->setMeta([
    'key1' => 'value',
    'key2' => 2
    'key3' => [1,2,3]
],'string' ); // all values will converted to string when you try to get them
$post->meta->key2; // "2" ( string )
$post->meta->key3; // "[1,2,3]" ( string json )

Third argument in createMeta and updateMeta methods is the same of setMeta method

In getMeta method

$post->setMeta('key' , 123);
$post->getMeta('key' , 'null' , 'string'); // "123" (string)
//----------------------------------
$post->setMeta('key' , [1,2,3] , 'string');
$post->getMeta('key' , 'null'); // "[1,2,3]" (string)
$post->getMeta('key' , 'null' , 'array'); // [1,2,3] (array)
$post->getMeta('key' , 'null' , 'boolean'); // true (boolean)

Custom Meta Table

By default, all meta-data for all models will be stored in the meta database table. But if you want, you can use a separate table for a particular model.

For example, you have Post, Comment and User models

You want to store all posts and comments meta in default table but the user's meta tags are in a special table To do this you have to take four steps :

First Step : you should publish package config file using this command :

$ php artisan vendor:publish --provider="Zoha\Meta\MetaServiceProvider" --tag=config

This command will place a file named meta.php in your config folder

Second Step : open config file in tables array you find a custom array . in this array you can add new tables name . for our example we add users_meta in this array to handle users meta :

'tables' => [
    'default' => 'meta',
    'custom'  => [
        'users_meta'
    ],
]

Third Step : you need to run migrate command to create new table .

$ php artisan migrate

If you have already migrated Meta migration, you should rollback this migrations and migrate it again ( to create new tables )

Final Step : now that the new table is made, you can introduce it to the User model (or any model you want) to handle its meta with this table . like this :

use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
    use \Zoha\Metable;

    protected $metaTable = 'users_meta';
}

Meta Model

you are free to use meta model in your project

use Zoha\Meta\Models\Meta;
$count = Meta::count();

Note : If you change meta values using meta model ( change database directly ) meta valuse that was loaded before will not be updated . If you want to update them you should call refreshLoadedMeta metahod :

use Zoha\Meta\Models\Meta;

$post->meta->key1; // exmaple : return 'test'
Meta::truncate();
$post->meta->key1; // still return 'test'

$post->refreshLoadeMeta();
$post->meta->key1; // will return null

Meta Table

The structure of the meta table is this :

Schema::create('meta', function (Blueprint $table) {
    $table->increments('id');
    $table->string('key',110);
    $table->text('value')->nullable();
    $table->string('type')->default(Meta::META_TYPE_STRING);
    $table->boolean('status')->default(true);
    $table->string('owner_type',80);
    $table->integer('owner_id');
    $table->unique(['key','owner_type','owner_id']);
    $table->timestamps();
});

License

License: MIT

contributing

This project is open for you contribution

laravel-meta's People

Contributors

axissxs avatar dependabot[bot] avatar hasaneksi avatar mhmiton avatar naabster avatar necenzurat avatar xghozt avatar zoha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

laravel-meta's Issues

Permissions

Hiya

Well done for creating a great package.

I was wondering if there is a way to be able to store permissions against a meta key?

What I need to be able to do is store which users/teams (using Jetstream) can read, edit, delete the metatag.

Then some way link that to Laravels search so that only those users/teams with read permission see results in the search.

Thanks for any help you can provide.

Do you plan on making a paid version with extra features?

Cheers

Nathan

Laravel v10.x supports

I prefer this package to the others and tried to use it on Laravel v.10.x but the installation failed due to:

Problem 1
    - zoha/laravel-meta[v1.1, ..., v1.5] require illuminate/support ^5.6 -> found illuminate/support[v5.6.0, ..., v5.8.36] but these were not loaded, likely because it conflicts with another require.
    - zoha/laravel-meta v1.6 requires illuminate/support ^5.8 -> found illuminate/support[v5.8.0, ..., v5.8.36] but these were not loaded, likely because it conflicts with another require.
    - zoha/laravel-meta 1.6.1 requires illuminate/support ^5.8|^6.0 -> found illuminate/support[v5.8.0, ..., v5.8.36, v6.0.0, ..., v6.20.44] but these were not loaded, likely because it conflicts with another require.
    - zoha/laravel-meta 1.7 requires illuminate/support ^5.8|^6.0|^7.0 -> found illuminate/support[v5.8.0, ..., v5.8.36, v6.0.0, 
..., v6.20.44, v7.0.0, ..., v7.30.6] but these were not loaded, likely because it conflicts with another require.
    - zoha/laravel-meta[1.8, ..., v1.9] require illuminate/support ^5.8|^6.0|^7.0|^8.0 -> found illuminate/support[v5.8.0, ..., v5.8.36, v6.0.0, ..., v6.20.44, v7.0.0, ..., v7.30.6, v8.0.0, ..., v8.83.27] but these were not loaded, likely because it conflicts with another require.
    - zoha/laravel-meta v2.0.0 requires laravel/framework ^8.0|^9.0 -> found laravel/framework[v8.0.0, ..., v8.83.27, v9.0.0, ..., v9.52.4] but it conflicts with your root composer.json require (^10.0).
    - Root composer.json requires zoha/laravel-meta * -> satisfiable by zoha/laravel-meta[v1.1, ..., v1.9, v2.0.0].

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific 
versions.

Thanks.

How to WhereMetaJsonContains in Package

Hi,
When Use Collection or array type for meta, how to query in Builder?

1234

when create attachment meta , how to query when we want all projectt tha has attachment with 3 or 5?

\App\Models\Project::whereMetaIn('attachment', ['3' , '5'])->get();

This Code Not Work?
Please Help

use of multiple tables in one model

protected $metaTable = ['posts_field','posts_detail_field'];

For example, is it possible to use 2 tables as post_field and post_detail in the Post model?

Add float data type

Feature request

Hi! Thank you for this awesome package, it's really useful.
It'd be great if you could add support for the float data type.
Thank you

Soft Deletes in laravel-meta

First off thank you so much for this wonderful package. Its a life saver coming from the wordpress world. Im wondering what would be the proper way to handle soft deletes ?

Temporary loaded meta not correct if event observer returns false

Hi, firstly to say thank you for this package, it is great.

I have been working on adding an approval workflow to an application that uses this package and I can listen to creating/updating events correctly and can intercept/block the create/update of metadata if conditions are not met, however it appears the package utilises temporary cached data against the model that updates with newly passed data even though the database record is not updated.

For example, if I create an observer and listen for the ::updating event on the Zoha\Meta\Models\Meta model and get it to return false, if I already have a meta value for key "updated_time" as (for example) "1641464807" then call something like the below:

$user = \Auth::user();
$user->setMeta('updated_time',time());
ddd($user->getMeta('updated_time'));

it will dump the latest time even though the meta database record does now get updated.

It appears that in SetMetaHelper.php you save the meta (in both executeUpdateMeta() and executeCreateMeta()) but do not check to see whether the data was actually saved or not before setting the value of the temporary loaded meta items.

Would it be possible to tweak the code to check to see if the save was completed successfully or not and update the temporary meta items cache accordingly? It may also be useful to then return false from UpdateMetaHelper::updateMeta and CreateMetaHelper::createMeta if the executions do not get saved due to events blocking them?

How to use whereMetaHas in pivot table

Hi there, firstly, thanks for this great package, I love it, it's working great so far.
However, I have some issues when using it in a pivot table.

I use meta in a pivot table where I store some user data related to the organization he belongs to.

I'm unable to query a user based on a meta stored in this pivot table.

Example:
I want to get all users that has a specific meta (e.g. account_id) inside the pivot table. Any ideas on how I can achieve this?

composer.json has the wrong source key

When I installed on a production environment, it installed version 1.1. Seemed to work locally but the files in my vendor folder on the server were very outdated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.