Skip to content

Commit 0ea669f

Browse files
committed
add json support
1 parent 043b311 commit 0ea669f

File tree

5 files changed

+107
-9
lines changed

5 files changed

+107
-9
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
namespace Mpociot\Versionable\Console;
4+
5+
use Illuminate\Console\Command;
6+
use Mpociot\Versionable\Version;
7+
8+
class ConvertEncoding extends Command
9+
{
10+
/**
11+
* The name and signature of the console command.
12+
*
13+
* @var string
14+
*/
15+
protected $signature = 'versionable:convert-encoding {--encoding=}';
16+
17+
/**
18+
* The console command description.
19+
*
20+
* @var string
21+
*/
22+
protected $description = 'Convert the encoding from JSON to serialize() or vice versa';
23+
24+
protected $encodingCheck = [
25+
'serialize' => '{',
26+
'json' => 'a:',
27+
];
28+
29+
/**
30+
* Execute the console command.
31+
*
32+
* @return mixed
33+
*/
34+
public function handle()
35+
{
36+
$encoding = $this->option('encoding') ?? config('versionable.encoding');
37+
$sourceEncoding = $encoding === 'json' ? 'serialize' : 'json';
38+
$versions = Version::query()->get();
39+
40+
foreach ($versions as $version) {
41+
if (!$this->validateData($version, $sourceEncoding)) {
42+
$this->error("Data does not appear to be as encoded $sourceEncoding: {$version->model_data}");
43+
44+
return;
45+
}
46+
47+
$version->model_data = $encoding === 'serialize'
48+
? serialize(json_decode($version->model_data, true))
49+
: json_encode(unserialize($version->model_data));
50+
51+
$version->save();
52+
}
53+
54+
$this->info("Converted {$versions->count()} models to '$encoding' encoding.");
55+
}
56+
57+
protected function validateData(Version $version, $sourceEncoding)
58+
{
59+
if (strpos($version->model_data, $this->encodingCheck[$sourceEncoding]) === 0) {
60+
return false;
61+
}
62+
63+
return true;
64+
}
65+
}

src/Mpociot/Versionable/Providers/ServiceProvider.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
class ServiceProvider extends LaravelServiceProvider
88
{
9+
protected $commands = [
10+
\Mpociot\Versionable\Console\ConvertEncoding::class,
11+
];
12+
913
/**
1014
* Register bindings in the container.
1115
*
@@ -14,6 +18,8 @@ class ServiceProvider extends LaravelServiceProvider
1418
public function register ()
1519
{
1620
$this->mergeConfigFrom(__DIR__.'/../../../config/config.php', 'versionable');
21+
22+
$this->commands($this->commands);
1723
}
1824

1925
/**

src/Mpociot/Versionable/Version.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ public function versionable()
3131
return $this->morphTo();
3232
}
3333

34+
/**
35+
* Return the encoding
36+
* @return mixed
37+
*/
38+
private function getEncoding()
39+
{
40+
return config('versionable.encoding', 'serialize');
41+
}
42+
3443
/**
3544
* Return the user responsible for this version
3645
* @return mixed
@@ -50,10 +59,11 @@ public function getModel()
5059
$modelData = is_resource($this->model_data)
5160
? stream_get_contents($this->model_data,-1,0)
5261
: $this->model_data;
62+
$modelDataEncoded = $this->getEncoding() === 'json' ? json_decode($modelData, true) : unserialize($modelData);
5363

5464
$model = new $this->versionable_type();
5565
$model->unguard();
56-
$model->fill(unserialize($modelData));
66+
$model->fill($modelDataEncoded);
5767
$model->exists = true;
5868
$model->reguard();
5969
return $model;

src/Mpociot/Versionable/VersionableTrait.php

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ trait VersionableTrait
1414
/**
1515
* Retrieve, if exists, the property that define that Version model.
1616
* If no property defined, use the default Version model.
17-
*
17+
*
1818
* Trait cannot share properties whth their class !
1919
* http://php.net/manual/en/language.oop5.traits.php
2020
* @return unknown|string
@@ -28,6 +28,16 @@ protected function getVersionClass()
2828
return config('versionable.version_model', Version::class);
2929
}
3030

31+
/**
32+
* Get the encoding, the default is serialize.
33+
*
34+
* @return string
35+
*/
36+
protected function getEncoding()
37+
{
38+
return config('versionable.encoding', 'serialize');
39+
}
40+
3141
/**
3242
* Private variable to detect if this is an update
3343
* or an insert
@@ -173,10 +183,12 @@ protected function versionablePostSave()
173183
$version->versionable_id = $this->getKey();
174184
$version->versionable_type = method_exists($this, 'getMorphClass') ? $this->getMorphClass() : get_class($this);
175185
$version->user_id = $this->getAuthUserId();
176-
186+
177187
$versionedHiddenFields = $this->versionedHiddenFields ?? [];
178188
$this->makeVisible($versionedHiddenFields);
179-
$version->model_data = serialize($this->attributesToArray());
189+
$version->model_data = $this->getEncoding() === 'json'
190+
? json_encode($this->attributesToArray())
191+
: serialize($this->attributesToArray());
180192
$this->makeHidden($versionedHiddenFields);
181193

182194
if (!empty( $this->reason )) {
@@ -191,16 +203,16 @@ protected function versionablePostSave()
191203

192204
/**
193205
* Delete old versions of this model when the reach a specific count.
194-
*
206+
*
195207
* @return void
196208
*/
197209
private function purgeOldVersions()
198210
{
199211
$keep = isset($this->keepOldVersions) ? $this->keepOldVersions : 0;
200-
212+
201213
if ((int)$keep > 0) {
202214
$count = $this->versions()->count();
203-
215+
204216
if ($count > $keep) {
205217
$this->getLatestVersions()
206218
->take($count)

src/config/config.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
* Feel free to change this, if you need specific version
88
* model logic.
99
*/
10-
'version_model' => \Mpociot\Versionable\Version::class
10+
'version_model' => \Mpociot\Versionable\Version::class,
1111

12-
];
12+
/*
13+
* The encoding to use for the model data encoding.
14+
* Default is 'serialize' and uses PHP serialize() but 'json' is also supported
15+
*/
16+
'encoding' => 'serialize',
17+
];

0 commit comments

Comments
 (0)