-
Notifications
You must be signed in to change notification settings - Fork 7
[0.12] Moved Plugin Scopes To Trait, Added Caching And Added TestCase #588
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1fa1c43
64d736d
c3001e5
9fde9ae
bd1dd54
8dd5f18
bba265b
0bf35be
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| use Illuminate\Database\Eloquent\Collection; | ||
| use Illuminate\Database\Eloquent\Model; | ||
|
|
||
| use Illuminate\Support\Facades\Cache; | ||
| use Illuminate\Support\Facades\Config; | ||
| use Illuminate\Support\Facades\File; | ||
| use Illuminate\Support\Facades\Log; | ||
|
|
@@ -38,19 +39,19 @@ class Plugin extends Model | |
| 'licence', | ||
| 'title', | ||
| ]; | ||
|
|
||
| private static function pluginDirectory() { | ||
| $pluginDirectory = config('app.plugin_directory'); | ||
| return base_path($pluginDirectory); | ||
| } | ||
|
|
||
| public static function getPluginPath(string $path = ''):string { | ||
| if($path === ''){ | ||
| return self::pluginDirectory(); | ||
| } | ||
| return self::pluginDirectory() . Str::start($path, '/'); | ||
| } | ||
|
|
||
| public static function isInstalled($name): bool { | ||
| return self::whereNotNull('installed_at')->where('name', $name)->exists(); | ||
| } | ||
|
|
@@ -62,7 +63,7 @@ public static function getInstalled(): Collection { | |
| public function slugName(): string { | ||
| return Str::slug($this->name); | ||
| } | ||
|
|
||
| public function getPath(string $path = ''): string { | ||
| $pluginPath = $this->name; | ||
| if($path !== ''){ | ||
|
|
@@ -94,7 +95,7 @@ public static function getPluginInfo($path, $isString = false): mixed { | |
|
|
||
| return json_decode(json_encode($xmlObject), true); | ||
| } | ||
|
|
||
| public function getInfo(){ | ||
| return self::getPluginInfo($this->getPath()); | ||
| } | ||
|
|
@@ -109,7 +110,7 @@ public function getMetadata(): array { | |
| $metadata[$field] = []; | ||
| continue; | ||
| } | ||
|
|
||
| $authors = $info[$field]['author']; | ||
| $metadata[$field] = is_array($authors) ? $authors : [$authors]; | ||
| } else { | ||
|
|
@@ -139,7 +140,7 @@ public function getChangelog(?string $since = null): string { | |
| } | ||
|
|
||
| public function getAccessPoints(): array { | ||
| $info = self::getInfo(base_path("app/Plugins/$this->name")); | ||
| $info = self::getInfo(); | ||
| $accesspoints = []; | ||
| $addedNames = []; | ||
| $addedPaths = []; | ||
|
|
@@ -170,51 +171,57 @@ public function getAccessPoints(): array { | |
| return $accesspoints; | ||
| } | ||
|
|
||
| public function getScopes(): array { | ||
| $info = self::getInfo(base_path("app/Plugins/$this->name"), false); | ||
| $scopes = []; | ||
| if($info !== false) { | ||
| if(array_key_exists('scopes', $info)) { | ||
| foreach($info['scopes'] as $scope) { | ||
| $attributes = $scope['@attributes']; | ||
| if(!array_key_exists('src', $attributes)) { | ||
| Log::error('<scope> attribute \'src\' is required'); | ||
| continue; | ||
| } | ||
| if(!array_key_exists('on', $attributes)) { | ||
| Log::error('<scope> attribute \'on\' is required'); | ||
| continue; | ||
| } | ||
|
|
||
| $src = $attributes['src']; | ||
| $on = $attributes['on']; | ||
|
|
||
| $srcDir = base_path("app/Plugins/$this->name/Scopes"); | ||
| if(!file_exists($srcDir) || !is_dir($srcDir)) { | ||
| Log::error('Missing \'Scopes\' directory'); | ||
| continue; | ||
| } | ||
| $srcPath = "{$srcDir}/{$src}"; | ||
| if(!file_exists($srcPath)) { | ||
| Log::error("Missing file '$src'"); | ||
| continue; | ||
| } | ||
| if(!class_exists($on)) { | ||
| Log::error("Class '{$on}' does not exist!"); | ||
| continue; | ||
| } | ||
| $className = Str::replaceEnd('.php', '', $src); | ||
| $namespacedSrc = "App\Plugins\\$this->name\Scopes\\$className"; | ||
| private function getScopeCacheKey(): string { | ||
| return 'plugin_scopes_' . $this->id; | ||
| } | ||
|
|
||
| if(!array_key_exists($on, $scopes)) { | ||
| $scopes[$on] = []; | ||
| public function getScopes(): array { | ||
| return Cache::rememberForever($this->getScopeCacheKey(), function() { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added the Cache to make access faster without the need to parse the info.xml on every request. |
||
| $info = self::getInfo(); | ||
| $scopes = []; | ||
| if($info !== false) { | ||
| if(array_key_exists('scopes', $info)) { | ||
| foreach($info['scopes'] as $scope) { | ||
| $attributes = $scope['@attributes']; | ||
| if(!array_key_exists('src', $attributes)) { | ||
| Log::error('<scope> attribute \'src\' is required'); | ||
| continue; | ||
| } | ||
| if(!array_key_exists('on', $attributes)) { | ||
| Log::error('<scope> attribute \'on\' is required'); | ||
| continue; | ||
| } | ||
|
|
||
| $src = $attributes['src']; | ||
| $on = $attributes['on']; | ||
|
|
||
| $srcDir = $this->getPath("Scopes"); | ||
| if(!file_exists($srcDir) || !is_dir($srcDir)) { | ||
| Log::error('Missing \'Scopes\' directory'); | ||
| continue; | ||
| } | ||
| $srcPath = $srcDir . DIRECTORY_SEPARATOR . $src; | ||
| if(!file_exists($srcPath)) { | ||
| Log::error("Missing file '$src'"); | ||
| continue; | ||
| } | ||
| if(!class_exists($on)) { | ||
| Log::error("Class '{$on}' does not exist!"); | ||
| continue; | ||
| } | ||
| $className = Str::replaceEnd('.php', '', $src); | ||
| $namespacedSrc = "App\\Plugins\\$this->name\\Scopes\\$className"; | ||
|
|
||
| if(!array_key_exists($on, $scopes)) { | ||
| $scopes[$on] = []; | ||
| } | ||
|
|
||
| $scopes[$on][] = $namespacedSrc; | ||
| } | ||
|
|
||
| $scopes[$on][] = $namespacedSrc; | ||
| } | ||
| } | ||
| } | ||
| return $scopes; | ||
| return $scopes; | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -344,11 +351,16 @@ public function updateUpdateState($fromInfoVersion): void { | |
| } | ||
| } | ||
|
|
||
| public function clearCache(): void { | ||
| Cache::forget($this->getScopeCacheKey()); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we can add all other plugin Caches, e.g. PluginHooks |
||
| } | ||
|
|
||
| public function handleInstallation(bool $isUpdate = false): void { | ||
| $this->runMigrations(); | ||
| $this->publishScript(); | ||
| $this->addPermissions(); | ||
| $this->installPresetsFromFile(); | ||
| $this->clearCache(); | ||
|
|
||
| if(!$isUpdate) { | ||
| $this->installed_at = Carbon::now(); | ||
|
|
@@ -369,7 +381,7 @@ public function handleUpdate(): string { | |
|
|
||
| public function handleUninstall(): void { | ||
| $this->removeScript(); | ||
|
|
||
| $this->clearCache(); | ||
| $this->installed_at = null; | ||
| $this->save(); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| <?php | ||
|
|
||
| namespace App\Traits; | ||
|
|
||
| use App\Plugin; | ||
|
|
||
| trait HasPluginScopes { | ||
| /** | ||
| * Register plugin scopes for this model | ||
| * | ||
| * Note: This method is called automatically by Laravel when the model boots. | ||
| */ | ||
| protected static function bootHasPluginScopes(): void { | ||
| // The try-catch is to prevent issues during installation/package discovery | ||
| try { | ||
| $pluginScopes = Plugin::getScopesFor(static::class); | ||
| foreach($pluginScopes as $pluginScope) { | ||
| static::addGlobalScope(new $pluginScope); | ||
| } | ||
| } catch(\Exception $e) { | ||
| // Fail silently during installation/package discovery | ||
| return; | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,13 +44,15 @@ | |
| ], | ||
| "psr-4": { | ||
| "App\\": "app/", | ||
| "App\\Plugins\\": "app/Plugins/", | ||
| "Database\\Factories\\": "database/factories/", | ||
| "Database\\Seeders\\": "database/seeders/" | ||
| } | ||
| }, | ||
| "autoload-dev": { | ||
| "psr-4": { | ||
| "Tests\\": "tests/" | ||
| "Tests\\": "tests/", | ||
| "App\\Plugins\\": "tests/assets/Plugins/" | ||
|
Comment on lines
+54
to
+55
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In tests we use this directory. Which was not detected by the auto loader when adding the scopes to the test plugins. |
||
| } | ||
| }, | ||
| "extra": { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,6 +35,16 @@ public function run() { | |
| 'created_at' => Carbon::createFromFormat('Y-m-d H:i:s', '2020-04-14 04:40:04', 'UTC'), | ||
| 'updated_at' => Carbon::createFromFormat('Y-m-d H:i:s', '2020-06-16 06:36:27', 'UTC'), | ||
| ), | ||
| 2 => array( | ||
| 'id' => 3, | ||
| 'name' => 'ScopePlugin', | ||
| 'version' => '3.2.0', | ||
| 'uuid' => '123e4567-e89b-12d3-a456-426614174004', | ||
| 'update_available' => null, | ||
| 'installed_at' => null, | ||
| 'created_at' => Carbon::createFromFormat('Y-m-d H:i:s', '2020-08-01 08:00:00', 'UTC'), | ||
| 'updated_at' => Carbon::createFromFormat('Y-m-d H:i:s', '2020-08-01 08:00:00', 'UTC'), | ||
| ), | ||
|
Comment on lines
+38
to
+47
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added the scope plugin to have a plugin that provides a scope. |
||
| )); | ||
|
|
||
| // Reset PostgreSQL sequence to continue from the highest ID | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was moved to
HasPluginScopes.phpthen we can add the trait to every model we want in the future.