Skip to content

Commit e6842e5

Browse files
author
Lupacescu Eduard
authored
Null repositories (#126)
* Allow instance of a repository with undefined model * Apply fixes from StyleCI (#124) * Allow instance of a repository with undefined model * Apply fixes from StyleCI (#125) * Route clear
1 parent 0fdf277 commit e6842e5

File tree

5 files changed

+128
-2
lines changed

5 files changed

+128
-2
lines changed

src/Commands/Refresh.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public function handle()
3131
$this->call('cache:clear');
3232
$this->call('config:cache');
3333
$this->call('view:clear');
34+
$this->call('route:clear');
3435
$this->call('optimize');
3536
}
3637
}

src/Repositories/NullModel.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Binaryk\LaravelRestify\Repositories;
4+
5+
use Binaryk\LaravelRestify\Traits\InteractWithSQLight;
6+
use Illuminate\Database\Eloquent\Model;
7+
8+
/**
9+
* @author Eduard Lupacescu <[email protected]>
10+
*/
11+
class NullModel extends Model
12+
{
13+
use InteractWithSQLight;
14+
15+
public $rows = [];
16+
}

src/Repositories/Repository.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ public static function uriKey()
7676
*/
7777
public static function newModel()
7878
{
79-
$model = static::$model;
79+
if (property_exists(static::class, 'model')) {
80+
$model = static::$model;
81+
} else {
82+
$model = NullModel::class;
83+
}
8084

8185
return new $model;
8286
}

src/Traits/AuthorizableModels.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Binaryk\LaravelRestify\Traits;
44

5+
use Binaryk\LaravelRestify\Repositories\Repository;
56
use Illuminate\Auth\Access\AuthorizationException;
67
use Illuminate\Database\Eloquent\Model;
78
use Illuminate\Database\Eloquent\ModelNotFoundException;
@@ -241,12 +242,22 @@ public function authorizedTo(Request $request, $ability)
241242
*/
242243
public function determineModel()
243244
{
244-
$model = $this instanceof Model ? $this : ($this->resource ?? null);
245+
$model = $this->isRepositoryContext() === false ? $this : ($this->resource ?? null);
245246

246247
if (is_null($model)) {
247248
throw new ModelNotFoundException(__('Model is not declared in :class', ['class' => self::class]));
248249
}
249250

250251
return $model;
251252
}
253+
254+
/**
255+
* Determine if the trait is used by repository or model.
256+
*
257+
* @return bool
258+
*/
259+
public static function isRepositoryContext()
260+
{
261+
return new static instanceof Repository;
262+
}
252263
}

src/Traits/InteractWithSQLight.php

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
namespace Binaryk\LaravelRestify\Traits;
4+
5+
use Illuminate\Database\Connectors\ConnectionFactory;
6+
use Illuminate\Support\Str;
7+
8+
/**
9+
* @author Caleb Porzio https://github.com/calebporzio/sushi/blob/master/src/Sushi.php
10+
*/
11+
trait InteractWithSQLight
12+
{
13+
protected static $sushiConnection;
14+
15+
public static function resolveConnection($connection = null)
16+
{
17+
return static::$sushiConnection;
18+
}
19+
20+
public static function bootSushi()
21+
{
22+
$instance = (new static);
23+
$cacheFileName = 'sushi-'.Str::kebab(str_replace('\\', '', static::class)).'.sqlite';
24+
$cacheDirectory = realpath(config('sushi.cache-path', storage_path('framework/cache')));
25+
$cachePath = $cacheDirectory.'/'.$cacheFileName;
26+
$modelPath = (new \ReflectionClass(static::class))->getFileName();
27+
28+
$states = [
29+
'cache-file-found-and-up-to-date' => function () use ($cachePath) {
30+
static::setSqliteConnection($cachePath);
31+
},
32+
'cache-file-not-found-or-stale' => function () use ($cachePath, $modelPath, $instance) {
33+
file_put_contents($cachePath, '');
34+
35+
static::setSqliteConnection($cachePath);
36+
37+
$instance->migrate();
38+
39+
touch($cachePath, filemtime($modelPath));
40+
},
41+
'no-caching-capabilities' => function () use ($instance) {
42+
static::setSqliteConnection(':memory:');
43+
44+
$instance->migrate();
45+
},
46+
];
47+
48+
switch (true) {
49+
case file_exists($cachePath) && filemtime($modelPath) === filemtime($cachePath):
50+
$states['cache-file-found-and-up-to-date']();
51+
break;
52+
53+
case file_exists($cacheDirectory) && is_writable($cacheDirectory):
54+
$states['cache-file-not-found-or-stale']();
55+
break;
56+
57+
default:
58+
$states['no-caching-capabilities']();
59+
break;
60+
}
61+
}
62+
63+
protected static function setSqliteConnection($database)
64+
{
65+
static::$sushiConnection = app(ConnectionFactory::class)->make([
66+
'driver' => 'sqlite',
67+
'database' => $database,
68+
]);
69+
}
70+
71+
public function migrate()
72+
{
73+
$rows = $this->rows;
74+
$firstRow = $rows[0];
75+
$tableName = $this->getTable();
76+
77+
throw_unless($rows, new \Exception('Sushi: $rows property not found on model: '.get_class($this)));
78+
79+
static::resolveConnection()->getSchemaBuilder()->create($tableName, function ($table) use ($firstRow) {
80+
foreach ($firstRow as $column => $value) {
81+
if ($column === 'id') {
82+
$table->increments('id');
83+
continue;
84+
}
85+
86+
$type = is_numeric($value) ? 'integer' : 'string';
87+
88+
$table->{$type}($column);
89+
}
90+
});
91+
92+
static::insert($rows);
93+
}
94+
}

0 commit comments

Comments
 (0)