From 5d8f8e963df585dd1d2c72df58f49064d3f2bf43 Mon Sep 17 00:00:00 2001 From: Lupacescu Eduard Date: Thu, 30 Jan 2020 10:11:44 +0200 Subject: [PATCH 1/5] Allow instance of a repository with undefined model --- src/Repositories/NullModel.php | 18 ++++++ src/Repositories/Repository.php | 6 +- src/Traits/AuthorizableModels.php | 23 +++++-- src/Traits/InteractWithSQLight.php | 96 ++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 src/Repositories/NullModel.php create mode 100644 src/Traits/InteractWithSQLight.php diff --git a/src/Repositories/NullModel.php b/src/Repositories/NullModel.php new file mode 100644 index 000000000..e9e970c11 --- /dev/null +++ b/src/Repositories/NullModel.php @@ -0,0 +1,18 @@ + + */ +class NullModel extends Model +{ + use InteractWithSQLight; + + public $rows = []; + +} diff --git a/src/Repositories/Repository.php b/src/Repositories/Repository.php index 123b5c1fa..e86732566 100644 --- a/src/Repositories/Repository.php +++ b/src/Repositories/Repository.php @@ -72,7 +72,11 @@ public static function uriKey() */ public static function newModel() { - $model = static::$model; + if (property_exists(static::class, 'model')) { + $model = static::$model; + } else { + $model = NullModel::class; + } return new $model; } diff --git a/src/Traits/AuthorizableModels.php b/src/Traits/AuthorizableModels.php index 8f3609556..e7a2ff4fc 100644 --- a/src/Traits/AuthorizableModels.php +++ b/src/Traits/AuthorizableModels.php @@ -2,6 +2,7 @@ namespace Binaryk\LaravelRestify\Traits; +use Binaryk\LaravelRestify\Repositories\Repository; use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\ModelNotFoundException; @@ -43,7 +44,7 @@ public static function authorizable() */ public function authorizeToShowAny(Request $request) { - if (! static::authorizable()) { + if ( ! static::authorizable()) { return; } @@ -60,7 +61,7 @@ public function authorizeToShowAny(Request $request) */ public static function authorizedToShowAny(Request $request) { - if (! static::authorizable()) { + if ( ! static::authorizable()) { return true; } @@ -78,7 +79,7 @@ public static function authorizedToShowAny(Request $request) */ public function authorizeToShowEvery(Request $request) { - if (! static::authorizable()) { + if ( ! static::authorizable()) { return; } @@ -95,7 +96,7 @@ public function authorizeToShowEvery(Request $request) */ public static function authorizedToShowEvery(Request $request) { - if (! static::authorizable()) { + if ( ! static::authorizable()) { return true; } @@ -136,7 +137,7 @@ public function authorizedToShow(Request $request) */ public static function authorizeToStore(Request $request) { - if (! static::authorizedToStore($request)) { + if ( ! static::authorizedToStore($request)) { throw new AuthorizationException('Unauthorized to store.'); } } @@ -241,7 +242,7 @@ public function authorizedTo(Request $request, $ability) */ public function determineModel() { - $model = $this instanceof Model ? $this : ($this->resource ?? null); + $model = $this->isRepositoryContext() === false ? $this : ($this->resource ?? null); if (is_null($model)) { throw new ModelNotFoundException(__('Model is not declared in :class', ['class' => self::class])); @@ -249,4 +250,14 @@ public function determineModel() return $model; } + + /** + * Determine if the trait is used by repository or model + * + * @return bool + */ + public static function isRepositoryContext() + { + return new static instanceof Repository; + } } diff --git a/src/Traits/InteractWithSQLight.php b/src/Traits/InteractWithSQLight.php new file mode 100644 index 000000000..658ac01e2 --- /dev/null +++ b/src/Traits/InteractWithSQLight.php @@ -0,0 +1,96 @@ + + */ +trait InteractWithSQLight +{ + protected static $sushiConnection; + + public static function resolveConnection($connection = null) + { + return static::$sushiConnection; + } + + public static function bootSushi() + { + $instance = (new static); + $cacheFileName = 'sushi-' . Str::kebab(str_replace('\\', '', static::class)) . '.sqlite'; + $cacheDirectory = realpath(config('sushi.cache-path', storage_path('framework/cache'))); + $cachePath = $cacheDirectory . '/' . $cacheFileName; + $modelPath = (new \ReflectionClass(static::class))->getFileName(); + + $states = [ + 'cache-file-found-and-up-to-date' => function () use ($cachePath) { + static::setSqliteConnection($cachePath); + }, + 'cache-file-not-found-or-stale' => function () use ($cachePath, $modelPath, $instance) { + file_put_contents($cachePath, ''); + + static::setSqliteConnection($cachePath); + + $instance->migrate(); + + touch($cachePath, filemtime($modelPath)); + }, + 'no-caching-capabilities' => function () use ($instance) { + static::setSqliteConnection(':memory:'); + + $instance->migrate(); + }, + ]; + + switch (true) { + case file_exists($cachePath) && filemtime($modelPath) === filemtime($cachePath): + $states['cache-file-found-and-up-to-date'](); + break; + + case file_exists($cacheDirectory) && is_writable($cacheDirectory): + $states['cache-file-not-found-or-stale'](); + break; + + default: + $states['no-caching-capabilities'](); + break; + } + } + + protected static function setSqliteConnection($database) + { + static::$sushiConnection = app(ConnectionFactory::class)->make([ + 'driver' => 'sqlite', + 'database' => $database, + ]); + } + + public function migrate() + { + $rows = $this->rows; + $firstRow = $rows[0]; + $tableName = $this->getTable(); + + throw_unless($rows, new \Exception('Sushi: $rows property not found on model: ' . get_class($this))); + + static::resolveConnection()->getSchemaBuilder()->create($tableName, function ($table) use ($firstRow) { + foreach ($firstRow as $column => $value) { + if ($column === 'id') { + $table->increments('id'); + continue; + } + + $type = is_numeric($value) ? 'integer' : 'string'; + + $table->{$type}($column); + } + }); + + static::insert($rows); + } + +} From 02888d2a47e57291b6ad1544f9f2f1f29e8f2aea Mon Sep 17 00:00:00 2001 From: Lupacescu Eduard Date: Thu, 30 Jan 2020 10:12:01 +0200 Subject: [PATCH 2/5] Apply fixes from StyleCI (#124) --- src/Repositories/NullModel.php | 2 -- src/Traits/AuthorizableModels.php | 14 +++++++------- src/Traits/InteractWithSQLight.php | 8 +++----- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/Repositories/NullModel.php b/src/Repositories/NullModel.php index e9e970c11..dab48b4bc 100644 --- a/src/Repositories/NullModel.php +++ b/src/Repositories/NullModel.php @@ -6,7 +6,6 @@ use Illuminate\Database\Eloquent\Model; /** - * @package Binaryk\LaravelRestify\Repositories; * @author Eduard Lupacescu */ class NullModel extends Model @@ -14,5 +13,4 @@ class NullModel extends Model use InteractWithSQLight; public $rows = []; - } diff --git a/src/Traits/AuthorizableModels.php b/src/Traits/AuthorizableModels.php index e7a2ff4fc..7f70a93b7 100644 --- a/src/Traits/AuthorizableModels.php +++ b/src/Traits/AuthorizableModels.php @@ -44,7 +44,7 @@ public static function authorizable() */ public function authorizeToShowAny(Request $request) { - if ( ! static::authorizable()) { + if (! static::authorizable()) { return; } @@ -61,7 +61,7 @@ public function authorizeToShowAny(Request $request) */ public static function authorizedToShowAny(Request $request) { - if ( ! static::authorizable()) { + if (! static::authorizable()) { return true; } @@ -71,7 +71,7 @@ public static function authorizedToShowAny(Request $request) } /** - * Determine if the resource should be available for the given request ( + * Determine if the resource should be available for the given request (. * * @param \Illuminate\Http\Request $request * @return void @@ -79,7 +79,7 @@ public static function authorizedToShowAny(Request $request) */ public function authorizeToShowEvery(Request $request) { - if ( ! static::authorizable()) { + if (! static::authorizable()) { return; } @@ -96,7 +96,7 @@ public function authorizeToShowEvery(Request $request) */ public static function authorizedToShowEvery(Request $request) { - if ( ! static::authorizable()) { + if (! static::authorizable()) { return true; } @@ -137,7 +137,7 @@ public function authorizedToShow(Request $request) */ public static function authorizeToStore(Request $request) { - if ( ! static::authorizedToStore($request)) { + if (! static::authorizedToStore($request)) { throw new AuthorizationException('Unauthorized to store.'); } } @@ -252,7 +252,7 @@ public function determineModel() } /** - * Determine if the trait is used by repository or model + * Determine if the trait is used by repository or model. * * @return bool */ diff --git a/src/Traits/InteractWithSQLight.php b/src/Traits/InteractWithSQLight.php index 658ac01e2..044cea9ee 100644 --- a/src/Traits/InteractWithSQLight.php +++ b/src/Traits/InteractWithSQLight.php @@ -6,7 +6,6 @@ use Illuminate\Support\Str; /** - * @package App\Models; * @author Eduard Lupacescu */ trait InteractWithSQLight @@ -21,9 +20,9 @@ public static function resolveConnection($connection = null) public static function bootSushi() { $instance = (new static); - $cacheFileName = 'sushi-' . Str::kebab(str_replace('\\', '', static::class)) . '.sqlite'; + $cacheFileName = 'sushi-'.Str::kebab(str_replace('\\', '', static::class)).'.sqlite'; $cacheDirectory = realpath(config('sushi.cache-path', storage_path('framework/cache'))); - $cachePath = $cacheDirectory . '/' . $cacheFileName; + $cachePath = $cacheDirectory.'/'.$cacheFileName; $modelPath = (new \ReflectionClass(static::class))->getFileName(); $states = [ @@ -75,7 +74,7 @@ public function migrate() $firstRow = $rows[0]; $tableName = $this->getTable(); - throw_unless($rows, new \Exception('Sushi: $rows property not found on model: ' . get_class($this))); + throw_unless($rows, new \Exception('Sushi: $rows property not found on model: '.get_class($this))); static::resolveConnection()->getSchemaBuilder()->create($tableName, function ($table) use ($firstRow) { foreach ($firstRow as $column => $value) { @@ -92,5 +91,4 @@ public function migrate() static::insert($rows); } - } From c835088a563091d2ad264bb86d4e6f2cc92482c8 Mon Sep 17 00:00:00 2001 From: Lupacescu Eduard Date: Thu, 30 Jan 2020 10:13:12 +0200 Subject: [PATCH 3/5] Allow instance of a repository with undefined model --- src/Traits/InteractWithSQLight.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Traits/InteractWithSQLight.php b/src/Traits/InteractWithSQLight.php index 658ac01e2..5c955e578 100644 --- a/src/Traits/InteractWithSQLight.php +++ b/src/Traits/InteractWithSQLight.php @@ -7,7 +7,7 @@ /** * @package App\Models; - * @author Eduard Lupacescu + * @author Caleb Porzio https://github.com/calebporzio/sushi/blob/master/src/Sushi.php */ trait InteractWithSQLight { From ea8b4b08981f6addb65441babe38111a7e553a3b Mon Sep 17 00:00:00 2001 From: Lupacescu Eduard Date: Thu, 30 Jan 2020 10:14:01 +0200 Subject: [PATCH 4/5] Apply fixes from StyleCI (#125) --- src/Traits/InteractWithSQLight.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Traits/InteractWithSQLight.php b/src/Traits/InteractWithSQLight.php index 5c955e578..7c310ac9c 100644 --- a/src/Traits/InteractWithSQLight.php +++ b/src/Traits/InteractWithSQLight.php @@ -6,7 +6,6 @@ use Illuminate\Support\Str; /** - * @package App\Models; * @author Caleb Porzio https://github.com/calebporzio/sushi/blob/master/src/Sushi.php */ trait InteractWithSQLight @@ -21,9 +20,9 @@ public static function resolveConnection($connection = null) public static function bootSushi() { $instance = (new static); - $cacheFileName = 'sushi-' . Str::kebab(str_replace('\\', '', static::class)) . '.sqlite'; + $cacheFileName = 'sushi-'.Str::kebab(str_replace('\\', '', static::class)).'.sqlite'; $cacheDirectory = realpath(config('sushi.cache-path', storage_path('framework/cache'))); - $cachePath = $cacheDirectory . '/' . $cacheFileName; + $cachePath = $cacheDirectory.'/'.$cacheFileName; $modelPath = (new \ReflectionClass(static::class))->getFileName(); $states = [ @@ -75,7 +74,7 @@ public function migrate() $firstRow = $rows[0]; $tableName = $this->getTable(); - throw_unless($rows, new \Exception('Sushi: $rows property not found on model: ' . get_class($this))); + throw_unless($rows, new \Exception('Sushi: $rows property not found on model: '.get_class($this))); static::resolveConnection()->getSchemaBuilder()->create($tableName, function ($table) use ($firstRow) { foreach ($firstRow as $column => $value) { @@ -92,5 +91,4 @@ public function migrate() static::insert($rows); } - } From 19f317518883848405b5e09a7e4e55d8dc75e294 Mon Sep 17 00:00:00 2001 From: Lupacescu Eduard Date: Fri, 31 Jan 2020 15:53:05 +0200 Subject: [PATCH 5/5] Route clear --- src/Commands/Refresh.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Commands/Refresh.php b/src/Commands/Refresh.php index d1619ba4e..a0aeeb8ab 100644 --- a/src/Commands/Refresh.php +++ b/src/Commands/Refresh.php @@ -31,6 +31,7 @@ public function handle() $this->call('cache:clear'); $this->call('config:cache'); $this->call('view:clear'); + $this->call('route:clear'); $this->call('optimize'); } }