You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Added ability to disable fluent meta access by setting `$disableFluentMeta` to `true`.
11
+
12
+
### Changed
13
+
14
+
* Removed laravel 7 and bellow support.
15
+
* Removed `__get` method.
16
+
* Removed `__set` method.
17
+
* Removed `__isset` method.
18
+
* Removed legacy getter.
19
+
* Removed `whereMeta` method in favor of `scopeWhereMeta`.
20
+
* Renamed `getMetaDefaultValue` method to `getDefaultMetaValue`.
21
+
* You can now set meta names starting with `meta`.
22
+
* Changed `saveMeta` method's visibility to public.
23
+
* Changed `getMetaData` method's visibility to public.
24
+
* Fluent setter will now check for any cast or mutator.
25
+
* Passing an array to `getMeta()` will now return a Collection with all the requested metas, even if they don't exist. non-existent metas value would be based on second parameter or `null` if nothing is provided.
26
+
27
+
### Fixed
28
+
29
+
* Fixed `getMeta` method's second parameter.
30
+
* Fixed duplicate queries executed when retrieving the models stored as meta.
31
+
* Fixed fluent getter treating relations as meta when the result is null.
Metable Trait adds the ability to access meta data as if it is a property on your model.
8
9
Metable is Fluent, just like using an eloquent model attribute you can set or unset metas. Follow along the documentation to find out more.
9
10
11
+
## Changelog
12
+
13
+
visit [CHANGELOG.md](CHANGELOG.md)
14
+
10
15
## Installation
11
16
12
17
#### Composer
13
18
14
-
Add this to your composer.json file, in the require object:
19
+
Laravel can be installed on laravel `8.x` or higher.
20
+
21
+
Run:
22
+
23
+
```
24
+
composer require kodeine/laravel-meta
25
+
```
26
+
27
+
For laravel 7.x or below visit [this link](https://github.com/kodeine/laravel-meta/tree/master).
15
28
16
-
```javascript
29
+
#### Upgrade guide
30
+
31
+
Change this line in `composer.json`:
32
+
33
+
```
17
34
"kodeine/laravel-meta": "master"
18
35
```
19
36
20
-
After that, run composer install to install the package.
37
+
to:
38
+
39
+
```
40
+
"kodeine/laravel-meta": "^2.0"
41
+
```
42
+
43
+
after that, run `composer update` to upgrade the package.
44
+
45
+
##### Upgrade notice
46
+
47
+
Laravel meta 2 has some backward incompatible changes that listed below:
48
+
49
+
1. Laravel 7 or lower not supported.
50
+
2. Removed the following methods: `__get`, `__set`, `__isset`. If you have defined any of these methods, then you probably have something like this in your model:
51
+
52
+
```php
53
+
class User extends Model{
54
+
use Metable{
55
+
__get as __metaGet
56
+
}
57
+
```
58
+
59
+
You need to remove `as` operator of the methods.
60
+
3. Removed legacy getter. in older version if you had a method called `getSomething()` then you could access return value of this method using `$model->something`. this is no longer the case, and you have to call `$model->getSomething()`.
61
+
4. Added new method `setAttribute` that overrides parent method.
62
+
5. Renamed `getMetaDefaultValue` method to `getDefaultMetaValue`.
63
+
6. Second parameter of `getMeta` method is now default value when meta is null.
64
+
7. Removed `whereMeta` method in favor of `scopeWhereMeta`. example: `User::whereMeta($key,$value)->get();`
65
+
8. Removed `getModelKey` method.
21
66
22
67
#### Migration Table Schema
68
+
69
+
This is an example migration. you need change parts of it.
70
+
71
+
In this example we assume you have a model named `Post`.
72
+
73
+
Meta table name should be your model's table name + `_meta` which in this case, model's table name is pluralized form of the model name. so the table name becomes `posts_meta`.
74
+
75
+
If you don't want to follow this naming convention and use something else for table name, make sure you add this name to your model's body:
76
+
77
+
```php
78
+
protected $metaTable = 'custom_meta_table';
79
+
```
80
+
81
+
the foreign key name should be your model's name + `_id` = `post_id`
82
+
83
+
If you used something else for foreign key, make sure you add this to your model's body:
84
+
85
+
```php
86
+
protected $metaKeyName = 'custom_foreign_key';
87
+
```
88
+
23
89
```php
24
90
/**
25
91
* Run the migrations.
@@ -29,9 +95,9 @@ After that, run composer install to install the package.
29
95
public function up()
30
96
{
31
97
Schema::create('posts_meta', function (Blueprint $table) {
Metable Trait will automatically set the meta table based on your model name.
73
-
Default meta table name would be, `model_meta`.
139
+
Default meta table name would be, `models_meta` where `models` is pluralized form of the model name.
74
140
In case you need to define your own meta table name, you can specify in model:
75
141
76
142
```php
@@ -82,15 +148,14 @@ class Post extends Eloquent
82
148
83
149
#### Default Model Attribute values
84
150
85
-
Additionally, you can set default values by setting an array called `$defaultMetaValues` on the model. Setting default has two side-effects:
86
-
87
-
1. If a meta attribute does not exist, the default value will be returned instead of `null`.
151
+
Additionally, you can set default values by setting an array called `$defaultMetaValues` on the model. Setting default has two side effects:
88
152
89
-
2. if you attempt to set a meta attribute to the default value, the row in the meta table will be removed, which will cause the default value to be returned, as per rule 1.
153
+
1. If a meta attribute does not exist, the default value will be returned instead of `null`.
154
+
2. if you attempt to set a meta attribute to the default value, the row in the meta table will be removed, which will cause the default value to be returned, as per rule 1.
90
155
91
-
This is be the desired and expected functionality for most projects, but be aware that you may need to reimplement default functionality with your own custom accessors and mutators if this functionality does not fit your needs.
156
+
This is being the desired and expected functionality for most projects, but be aware that you may need to reimplement default functionality with your own custom accessors and mutators if this functionality does not fit your needs.
92
157
93
-
This functionality is most suited for meta entries that note exceptions to rules. For example: employees sick out of office (default value: in office), nodes taken down for maintance (default value: node up), etc. This means the table doesn't need to store data on every entry which is in the expected state, only those rows in the exceptional state, and allows the rows to have a default state upon creation without needing to add code to write it.
158
+
This functionality is most suited for meta entries that note exceptions to rules. For example: employees sick out of office (default value: in office), nodes taken down for maintenance (default value: node up), etc. This means the table doesn't need to store data on every entry which is in the expected state, only those rows in the exceptional state, and allows the rows to have a default state upon creation without needing to add code to write it.
94
159
95
160
```
96
161
public $defaultMetaValues = [
@@ -99,6 +164,7 @@ This functionality is most suited for meta entries that note exceptions to rules
99
164
```
100
165
101
166
#### Gotcha
167
+
102
168
When you extend a model and still want to use the same meta table you must override `getMetaKeyName` function.
103
169
104
170
```
@@ -116,17 +182,15 @@ class Slideshow extends Post
116
182
}
117
183
```
118
184
119
-
120
-
121
185
## Working With Meta
122
186
123
187
#### Setting Content Meta
124
188
125
189
To set a meta value on an existing piece of content or create a new data:
126
190
127
191
> **Fluent way**, You can **set meta flawlessly** as you do on your regular eloquent models.
128
-
Metable checks if attribute belongs to model, if not it will
129
-
access meta model to append or set a new meta.
192
+
> Metable checks if attribute belongs to model, if not it will
193
+
> access meta model to append or set a new meta.
130
194
131
195
```php
132
196
$post = Post::find(1);
@@ -169,6 +233,13 @@ $post->save();
169
233
170
234
> **Note:** If a piece of content already has a meta the existing value will be updated.
171
235
236
+
You can also save metas with `saveMeta` without saving the model itself:
237
+
238
+
```php
239
+
$post->content = 'some content goes here'; // meta data attribute
240
+
$post->saveMeta(); // will save metas to database but won't save the model itself
241
+
```
242
+
172
243
#### Unsetting Content Meta
173
244
174
245
Similarly, you may unset meta from an existing piece of content:
@@ -214,15 +285,29 @@ To see if a piece of content has a meta:
214
285
```php
215
286
if (isset($post->content)) {
216
287
288
+
}
289
+
// or
290
+
if ($post->hasMeta('content')){
291
+
217
292
}
218
293
```
219
294
295
+
You may also check if model has multiple metas:
296
+
297
+
```php
298
+
$post->hasMeta(['content','views']); // returns true only if all the metas exist
299
+
// or
300
+
$post->hasMeta('content|views');
301
+
// or
302
+
$post->hasMeta('content,views');
303
+
```
304
+
220
305
#### Retrieving Meta
221
306
222
307
To retrieve a meta value on a piece of content, use the `getMeta` method:
223
308
224
309
> **Fluent way**, You can access meta data as if it is a property on your model.
225
-
Just like you do on your regular eloquent models.
310
+
> Just like you do on your regular eloquent models.
226
311
227
312
```php
228
313
$post = Post::find(1);
@@ -242,13 +327,38 @@ Or specify a default value, if not set:
242
327
$post = $post->getMeta('content', 'Something');
243
328
```
244
329
330
+
> **Note:** default values set in defaultMetaValues property take precedence over default value passed to this method.
331
+
245
332
You may also retrieve more than one meta at a time and get an illuminate collection:
$this->assertTrue( isset( $user->foo ), 'Fluent meta should be set.' );
75
+
$this->assertEquals( 'bar', $user->foo, 'Fluent setter not working.' );
76
+
$this->assertEquals( 'bar', is_null( $meta = $metaData->first() ) ? null : $meta->value, 'Fluent setter did not save meta to database.' );
77
+
78
+
$user->foo = 'baz';
79
+
80
+
$this->assertEquals( 'baz', $user->foo, 'Fluent setter did not update existing meta before save.' );
81
+
$this->assertEquals( 'bar', is_null( $meta = $metaData->first() ) ? null : $meta->value, 'Fluent setter should not update meta in database before save.' );
82
+
83
+
$user->save();
84
+
85
+
$this->assertEquals( 'baz', $user->foo, 'Fluent setter did not update existing meta.' );
86
+
$this->assertEquals( 'baz', is_null( $meta = $metaData->first() ) ? null : $meta->value, 'Fluent setter did not update meta in database.' );
87
+
$this->assertEquals( 1, $metaData->count(), 'Fluent setter created multiple rows for one meta data.' );
88
+
89
+
unset( $user->foo );
90
+
91
+
$this->assertNull( $user->foo, 'Unsetter did not work before save.' );
92
+
$this->assertEquals( 'baz', is_null( $meta = $metaData->first() ) ? null : $meta->value, 'Fluent unsetter should not remove meta from database before save.' );
93
+
$this->assertEquals( 1, $metaData->count(), 'Fluent unsetter should not remove meta from database before save.' );
94
+
$this->assertFalse( isset( $user->foo ), 'Fluent meta should not be set before save.' );
95
+
96
+
$user->save();
97
+
98
+
$this->assertNull( $user->foo, 'Unsetter did not work.' );
99
+
$this->assertNull( $metaData->first(), 'Fluent unsetter did not remove meta from database.' );
100
+
$this->assertEquals( 0, $metaData->count(), 'Fluent unsetter did not remove meta from database.' );
101
+
$this->assertFalse( isset( $user->foo ), 'Fluent meta should not be set.' );
102
+
103
+
$user->foo = 'bar';
104
+
$user->save();
105
+
$user->delete();
106
+
107
+
$this->assertEquals( 0, $metaData->count(), 'Meta should be deleted from database after deleting user.' );
108
+
}
109
+
110
+
publicfunctiontestDisableFluentMeta() {
111
+
$user = newUser;
112
+
$user->disableFluentMeta = true;
113
+
114
+
$user->foo = 'bar';
115
+
116
+
$this->assertNull( $user->getMeta( 'foo' ), 'Meta should be null.' );
117
+
$this->assertFalse( $user->hasMeta( 'foo' ), 'Meta should not be set.' );
118
+
119
+
$user->setMeta( 'foo', 'baz' );
120
+
121
+
$this->assertNotEquals( 'baz', $user->foo, 'Fluent getter should not be changed.' );
122
+
$this->assertEquals( 'baz', $user->getMeta( 'foo' ), 'meta should be set.' );
123
+
124
+
unset( $user->foo );
125
+
126
+
$this->assertEquals( 'baz', $user->getMeta( 'foo' ), 'meta should be set.' );
127
+
128
+
$user->foo = 'bar';
129
+
$user->unsetMeta( 'foo' );
130
+
131
+
$this->assertNull( $user->getMeta( 'foo' ), 'meta should not be set.' );
132
+
$this->assertEquals( 'bar', $user->foo, 'Fluent getter should not be changed.' );
$this->assertTrue( $user->relationLoaded( 'metas' ), 'Metas relation should be loaded' );
224
+
225
+
$this->assertEquals( 'baz', $user->getMeta( 'foo' ), 'Meta method getMeta did not return correct value' );
226
+
$this->assertEquals( 'bar', $user->getMeta( 'bas' ), 'Meta method getMeta did not return correct value' );
227
+
$this->assertSame( ['foo' => 'baz', 'bas' => 'bar'], $user->getMeta()->toArray(), 'Meta method getMeta did not return correct value' );
228
+
$this->assertSame( ['foo' => 'baz', 'bas' => 'bar'], $user->getMeta( ['foo', 'bas'] )->toArray(), 'Meta method getMeta did not return correct value' );
229
+
$this->assertSame( ['foo' => 'baz', 'bas' => 'bar'], $user->getMeta( 'foo|bas' )->toArray(), 'Meta method getMeta did not return correct value' );
230
+
$this->assertSame( ['foo' => 'baz'], $user->getMeta( ['foo'] )->toArray(), 'Meta method getMeta did not return correct value' );
231
+
232
+
$this->assertTrue( $user->hasMeta( 'foo' ), 'Meta method hasMeta did not return correct value' );
233
+
$this->assertFalse( $user->hasMeta( 'bar' ), 'Meta method hasMeta did not return correct value' );
234
+
$this->assertTrue( $user->hasMeta( ['foo', 'bas'] ), 'Meta method hasMeta did not return correct value' );
235
+
$this->assertTrue( $user->hasMeta( ['foo|bas'] ), 'Meta method hasMeta did not return correct value' );
236
+
$this->assertFalse( $user->hasMeta( ['foo', 'bar'] ), 'Meta method hasMeta did not return correct value' );
237
+
238
+
$user->unsetMeta( 'foo' );
239
+
$this->assertFalse( $user->hasMeta( 'foo' ), 'Meta method hasMeta did not return correct value' );
240
+
$this->assertNull( $user->getMeta( 'foo' ), 'Meta method getMeta did not return correct value' );
241
+
242
+
$user->setMeta( 'foo', 'bar' );
243
+
$user->setMeta( 'bar', 'baz' );
244
+
$user->unsetMeta( ['foo', 'bas'] );
245
+
246
+
$this->assertFalse( $user->hasMeta( 'foo' ), 'Meta method hasMeta did not return correct value' );
247
+
$this->assertFalse( $user->hasMeta( 'bas' ), 'Meta method hasMeta did not return correct value' );
248
+
$this->assertFalse( $user->hasMeta( ['foo', 'bas'] ), 'Meta method hasMeta did not return correct value' );
249
+
$this->assertFalse( $user->hasMeta( ['foo|bas'] ), 'Meta method hasMeta did not return correct value' );
250
+
$this->assertFalse( $user->hasMeta( ['foo', 'bar'] ), 'Meta method hasMeta did not return correct value' );
251
+
$this->assertTrue( $user->hasMeta( ['bar'] ), 'Meta method hasMeta did not return correct value' );
252
+
253
+
$user->delete();
254
+
}
255
+
256
+
publicfunctiontestDefaultParameterInGetMeta() {
257
+
$user = newUser;
258
+
259
+
$this->assertEquals( 'default_value', $user->getMeta( 'foo', 'default_value' ), 'Default parameter should be returned when meta is null' );
260
+
$this->assertSame( ['foo' => 'foo_value', 'bar' => 'bar_value'], $user->getMeta( ['foo', 'bar'], ['foo' => 'foo_value', 'bar' => 'bar_value'] )->toArray(), 'Default parameter should be returned when meta is null' );
261
+
$this->assertSame( ['foo' => 'default_value', 'bar' => 'default_value'], $user->getMeta( ['foo', 'bar'], 'default_value' )->toArray(), 'Default parameter should be returned when meta is null' );
262
+
263
+
$this->assertEquals( 'default_meta_value', $user->getMeta( 'default_meta_key', 'bar' ), 'Default value set in defaultMetaValues property should be returned when meta is null' );
264
+
$this->assertSame( ['default_meta_key' => 'default_meta_value', 'foo' => 'bar'], $user->getMeta( ['default_meta_key', 'foo'], ['default_meta_key' => 'bar', 'foo' => 'bar'] )->toArray(), 'Default value set in defaultMetaValues property should be returned when meta is null' );
265
+
$this->assertSame( ['default_meta_key' => 'default_meta_value', 'foo' => 'bar'], $user->getMeta( ['default_meta_key', 'foo'], 'bar' )->toArray(), 'Default value set in defaultMetaValues property should be returned when meta is null' );
266
+
}
267
+
268
+
publicfunctiontestHasColumn() {
269
+
$user = newUser;
270
+
$this->assertTrue( $user->hasColumn( 'name' ), 'User does not have "name" column' );
271
+
$this->assertFalse( $user->hasColumn( 'foo' ), 'User should not have "foo" column' );
272
+
}
273
+
274
+
publicfunctiontestHideMeta() {
275
+
$user = newUser;
276
+
$user->setMeta( 'foo', 'bar' );
277
+
$user->hideMeta = false;
278
+
279
+
$this->assertArrayHasKey( 'meta_data', $user->toArray(), 'Metas should be included in array' );
280
+
$this->assertArrayHasKey( 'foo', $user->toArray()['meta_data'], 'Meta should be included in array' );
281
+
282
+
$user->hideMeta = true;
283
+
$this->assertArrayNotHasKey( 'meta_data', $user->toArray(), 'Metas should not be included in array' );
0 commit comments