From 88b3d79f4c1b6c1b4efcd4a5a9a856fe6e67f6a7 Mon Sep 17 00:00:00 2001 From: PatrickePatate Date: Wed, 20 Nov 2024 22:24:55 +0100 Subject: [PATCH 1/2] WIP: Handle Custom Filesystem Definition --- config/ozu-client.php | 29 ++++- src/Client.php | 8 ++ src/Console/ConfigureCmsCommand.php | 25 +++- .../Storage/OzuAbstractCustomStorage.php | 19 +++ src/OzuCms/Storage/OzuCustomFTPStorage.php | 113 +++++++++++++++++ src/OzuCms/Storage/OzuCustomS3Storage.php | 91 +++++++++++++ src/OzuServiceProvider.php | 5 + .../Thumbnails/CustomStorageThumbnail.php | 120 ++++++++++++++++++ 8 files changed, 408 insertions(+), 2 deletions(-) create mode 100644 src/OzuCms/Storage/OzuAbstractCustomStorage.php create mode 100644 src/OzuCms/Storage/OzuCustomFTPStorage.php create mode 100644 src/OzuCms/Storage/OzuCustomS3Storage.php create mode 100644 src/Support/Thumbnails/CustomStorageThumbnail.php diff --git a/config/ozu-client.php b/config/ozu-client.php index 11bf06d..fcd6afd 100644 --- a/config/ozu-client.php +++ b/config/ozu-client.php @@ -1,15 +1,42 @@ [ -// \App\Models\Project::class, + // \App\Models\Project::class, ], // The Ozu unique key of the website to use 'website_key' => env('OZU_WEBSITE_KEY'), + + // If you want to use custom storage for your files, you can configure it here. + // If you change your configuration after having uploaded files, you will have to manually move them to the new storage + // Or reset them in ozu. + // This is an example of how to configure a custom S3 storage: + + /* 'custom_storage' => OzuCustomS3Storage::make() + ->setBucketName(env('OZU_S3_BUCKET')) + ->setRegion(env('OZU_S3_REGION')) + ->setKey(env('OZU_S3_KEY')) + ->setSecret(env('OZU_S3_SECRET')) + ->setEndpoint(env('OZU_S3_ENDPOINT')) + ->setUsePathStyleEndpoint(env('OZU_S3_USE_PATH_STYLE_ENDPOINT')) + ,*/ + + // This is an example of how to configure a custom FTP storage: + /*'custom_storage' => OzuCustomFTPStorage::make() + ->setHost(env('OZU_FTP_HOST')) + ->setPort(env('OZU_FTP_PORT')) + ->setUsername(env('OZU_FTP_USERNAME')) + ->setPassword(env('OZU_FTP_PASSWORD')) + ->setRootPath(env('OZU_FTP_ROOT_PATH')) + ,*/ + // The API key to use to authenticate with the Ozu API // (do not fill this value here, use the .env file instead) 'api_key' => env('OZU_API_KEY'), diff --git a/src/Client.php b/src/Client.php index 5dea9c4..da2c872 100644 --- a/src/Client.php +++ b/src/Client.php @@ -23,6 +23,14 @@ public function updateCollectionSharpConfiguration(string $collectionKey, array ); } + public function updateCustomStorageConfiguration(array $configuration): void + { + $this->http()->post( + '/storage/configure', + $configuration + ); + } + public function apiKey(): ?string { return $this->apiKey; diff --git a/src/Console/ConfigureCmsCommand.php b/src/Console/ConfigureCmsCommand.php index 1591645..d6801bf 100644 --- a/src/Console/ConfigureCmsCommand.php +++ b/src/Console/ConfigureCmsCommand.php @@ -9,6 +9,7 @@ use Code16\OzuClient\OzuCms\OzuCollectionListConfig; use Code16\OzuClient\OzuCms\OzuCollectionConfig; use Code16\OzuClient\OzuCms\List\OzuColumn; +use Code16\OzuClient\OzuCms\Storage\OzuAbstractCustomStorage; use Illuminate\Console\Command; use Illuminate\Http\Client\RequestException; use Illuminate\Support\Facades\Schema; @@ -80,7 +81,7 @@ public function handle(Client $ozuClient): int 'text', 'json' => 'text', default => 'string', } - ]) + ]), ]; }) ->each(function (array $collection) use ($ozuClient) { @@ -102,6 +103,28 @@ public function handle(Client $ozuClient): int } }); + if(config('ozu-client.custom_storage')) { + $customStorage = config('ozu-client.custom_storage'); + + if($customStorage instanceof OzuAbstractCustomStorage) { + if($customStorage->meetRequirements()) { + $ozuClient->updateCustomStorageConfiguration(config('ozu-client.custom_storage')->toArray()); + } else { + $this->error( + sprintf('Custom storage does not meet requirements. Missing : %s', + $customStorage->whatsMissing()->join(', ') + ) + ); + return self::FAILURE; + } + } else { + $this->error('Custom storage must be an instance of OzuAbstractCustomStorage'); + return self::FAILURE; + } + } else { + $ozuClient->updateCustomStorageConfiguration([]); + } + $this->info('CMS configuration sent to Ozu.'); return self::SUCCESS; diff --git a/src/OzuCms/Storage/OzuAbstractCustomStorage.php b/src/OzuCms/Storage/OzuAbstractCustomStorage.php new file mode 100644 index 0000000..048dcb1 --- /dev/null +++ b/src/OzuCms/Storage/OzuAbstractCustomStorage.php @@ -0,0 +1,19 @@ +host = $host; + + return $this; + } + + public function setUsername(string $username): self + { + $this->username = $username; + + return $this; + } + + public function setPassword(string $password): self + { + $this->password = $password; + + return $this; + } + + public function setPort(int $port): self + { + $this->port = $port; + + return $this; + } + + public function setRootPath(string $root): self + { + $this->root = $root; + + return $this; + } + + public function setPassive(bool $passive): self + { + $this->passive = $passive; + + return $this; + } + + public function setSsl(bool $ssl): self + { + $this->ssl = $ssl; + + return $this; + } + + public function setTimeout(int $timeout): self + { + if($timeout > 30) + { + throw new Exception('Timeout must be less than 30 seconds'); + } + + $this->timeout = $timeout; + + return $this; + } + + public function toArray(): array + { + return [ + 'driver' => 'ftp', + 'host' => $this->host, + 'username' => $this->username, + 'password' => $this->password, + 'port' => $this->port, + 'root' => $this->root, + 'passive' => $this->passive, + 'ssl' => $this->ssl, + 'timeout' => $this->timeout, + ]; + } + + public function meetRequirements(): bool + { + if(!$this->host || !$this->username || !$this->password) + { + return false; + } + + return true; + } + + public function whatsMissing(): Collection + { + return collect([ + !$this->host ? 'Host' : null, + !$this->username ? 'Username' : null, + !$this->password ? 'Password' : null, + ])->filter(); + } +} diff --git a/src/OzuCms/Storage/OzuCustomS3Storage.php b/src/OzuCms/Storage/OzuCustomS3Storage.php new file mode 100644 index 0000000..bfc191a --- /dev/null +++ b/src/OzuCms/Storage/OzuCustomS3Storage.php @@ -0,0 +1,91 @@ +bucket = $bucket; + + return $this; + } + + public function setRegion(string $region): self + { + $this->region = $region; + + return $this; + } + + public function setKey(string $key): self + { + $this->key = $key; + + return $this; + } + + public function setSecret(string $secret): self + { + $this->secret = $secret; + + return $this; + } + + public function setEndpoint(string $endpoint): self + { + $this->endpoint = $endpoint; + + return $this; + } + + public function setUsePathStyleEndpoint(bool $use_path_style_endpoint): self + { + $this->use_path_style_endpoint = $use_path_style_endpoint; + + return $this; + } + + public function toArray(): array + { + return [ + 'driver' => 's3', + 'bucket' => $this->bucket, + 'region' => $this->region, + 'key' => $this->key, + 'secret' => $this->secret, + 'endpoint' => $this->endpoint, + 'use_path_style_endpoint' => $this->use_path_style_endpoint, + ]; + } + + public function meetRequirements(): bool + { + if(!$this->bucket || !$this->region || !$this->key || !$this->secret || !$this->endpoint) + { + return false; + } + + return true; + } + + public function whatsMissing(): Collection + { + return collect([ + !$this->bucket ? 'Host' : null, + !$this->region ? 'Region' : null, + !$this->key ? 'Key' : null, + !$this->secret ? 'Secret' : null, + !$this->endpoint ? 'Endpoint' : null, + ])->filter(); + } +} diff --git a/src/OzuServiceProvider.php b/src/OzuServiceProvider.php index c746c03..2fab160 100644 --- a/src/OzuServiceProvider.php +++ b/src/OzuServiceProvider.php @@ -5,6 +5,7 @@ use Code16\OzuClient\Deploy\DeployServiceProvider; use Code16\OzuClient\Support\Pagination\StaticLengthAwarePaginator; use Code16\OzuClient\Support\Pagination\StaticPaginator; +use Code16\OzuClient\Support\Thumbnails\CustomStorageThumbnail; use Code16\OzuClient\Support\Thumbnails\ImageKitThumbnail; use Code16\OzuClient\Support\Thumbnails\KeyCdnThumbnail; use Code16\OzuClient\Support\Thumbnails\LocalThumbnail; @@ -48,6 +49,10 @@ public function register() $this->app->bind(Paginator::class, StaticPaginator::class); $this->app->bind(LengthAwarePaginator::class, StaticLengthAwarePaginator::class); $this->app->bind(Thumbnail::class, function ($app) { + if (!$app->environment(['local', 'testing']) && config('ozu-client.custom_storage')) { + return $app->make(CustomStorageThumbnail::class); + } + if (!$app->environment('production') || !config('ozu-client.cdn_url')) { return $app->make(LocalThumbnail::class); } diff --git a/src/Support/Thumbnails/CustomStorageThumbnail.php b/src/Support/Thumbnails/CustomStorageThumbnail.php new file mode 100644 index 0000000..4656b15 --- /dev/null +++ b/src/Support/Thumbnails/CustomStorageThumbnail.php @@ -0,0 +1,120 @@ +imageManager = new ImageManager(new Driver()); + $this->storage = app(FilesystemManager::class); + } + + public function make(?int $width, ?int $height = null, bool $fit = false): ?string + { + if (! $this->mediaModel->disk || ! $this->mediaModel->file_name) { + return null; + } + + $this->width = $width ?: null; + $this->height = $height ?: null; + $this->fit = $fit; + + $thumbnailPath = sprintf( + 'thumbnails/%s/%s-%s_f%s_q-%s/%s', + dirname($this->mediaModel->file_name), + $width, + $height, + $fit ? '1' : '0', + $this->quality, + basename($this->mediaModel->file_name), + ); + + // Strip double / + $thumbnailPath = Str::replace('//', '/', $thumbnailPath); + + return $this->generateThumbnail( + $this->mediaModel->disk, + $this->mediaModel->file_name, + $thumbnailPath, + ); + } + + private function generateThumbnail(string $sourceDisk, string $sourceRelPath, string $thumbnailPath): ?string + { + $thumbnailDisk = $this->storage->disk('public'); + + $sourceDisk = config('ozu-client.custom_storage') ? 'custom' : $sourceDisk; + + if (!$thumbnailDisk->exists($thumbnailPath)) { + // Create thumbnail directories if needed + if (! $thumbnailDisk->exists(dirname($thumbnailPath))) { + $thumbnailDisk->makeDirectory(dirname($thumbnailPath)); + } + + try { + $sourceImg = $this->imageManager->read( + config('ozu-client.custom_storage') + ? $this->storage->build(config('ozu-client.custom_storage')->toArray())->get($sourceRelPath) + : $this->storage->disk($sourceDisk)->get($sourceRelPath), + ); + + if ($this->fit) { + $sourceImg->cover($this->width, $this->height ?: $this->width); + } else { + $sourceImg->scaleDown($this->width, $this->height); + } + + $thumbnailDisk->put($thumbnailPath, $sourceImg->toJpeg(quality: $this->quality)); + } catch (CircularDependencyException|BindingResolutionException|FileNotFoundException|DecoderException) { + return null; + } + } + + return $thumbnailDisk->url($thumbnailPath) + .($this->appendTimestamp ? '?'.$thumbnailDisk->lastModified($thumbnailPath) : ''); + } + + public function download(): ?string + { + $filesDisk = $this->storage->disk('public'); + + if (!$filesDisk->exists($this->mediaModel->file_name)) { + // Create files directories if needed + if (!$filesDisk->exists(dirname($this->mediaModel->file_name))) { + $filesDisk->makeDirectory(dirname($this->mediaModel->file_name)); + } + + try{ + if(config('ozu-client.custom_storage')) + { + $filesDisk->put($this->mediaModel->file_name, $this->storage->build(config('ozu-client.custom_storage')->toArray())->get($this->mediaModel->file_name)); + } else { + $filesDisk->put($this->mediaModel->file_name, $this->storage->disk($this->mediaModel->disk)->get($this->mediaModel->file_name)); + } + + }catch (BindingResolutionException|CircularDependencyException|FileNotFoundException|DecoderException) { + return null; + } + } + + return $this->storage->disk("public")->url($this->mediaModel->file_name); + } +} From 537c02e05b5d251fc46bb8832a02a0b2afaab799 Mon Sep 17 00:00:00 2001 From: PatrickePatate Date: Fri, 20 Dec 2024 14:10:02 +0000 Subject: [PATCH 2/2] Fix styling --- config/ozu-client.php | 3 +- database/factories/MediaFactory.php | 12 +- src/Client.php | 3 +- src/Console/ConfigureCmsCommand.php | 42 +++--- src/Deploy/Crawler/Observer.php | 4 +- src/Deploy/DeployServiceProvider.php | 2 +- src/Deploy/Jobs/CrawlSite.php | 4 +- src/Deploy/Jobs/CrawlSiteHandler.php | 2 +- src/Deploy/Routing/UrlGenerator.php | 2 +- src/Deploy/RoutingServiceProvider.php | 4 +- src/Eloquent/Media.php | 11 +- src/OzuCms/Form/OzuBelongsToField.php | 1 - src/OzuCms/Form/OzuEditorField.php | 8 +- src/OzuCms/Form/OzuField.php | 7 +- src/OzuCms/Form/OzuFileListField.php | 2 + src/OzuCms/Form/OzuImageField.php | 3 + src/OzuCms/Form/OzuSelectField.php | 3 + src/OzuCms/List/OzuBelongsToFilter.php | 5 +- src/OzuCms/List/OzuColumn.php | 6 +- src/OzuCms/List/OzuDateColumn.php | 2 - src/OzuCms/OzuCollectionConfig.php | 9 +- src/OzuCms/OzuCollectionFormConfig.php | 14 +- src/OzuCms/OzuCollectionListConfig.php | 4 +- .../Storage/OzuAbstractCustomStorage.php | 8 +- src/OzuCms/Storage/OzuCustomFTPStorage.php | 19 ++- src/OzuCms/Storage/OzuCustomS3Storage.php | 18 ++- src/OzuServiceProvider.php | 6 +- src/Support/Database/OzuSeeder.php | 4 +- src/Support/Image.php | 9 +- src/Support/ImageCollection.php | 4 +- src/Support/Thumbnails/CdnThumbnail.php | 4 +- .../Thumbnails/CustomStorageThumbnail.php | 23 ++-- src/Support/Thumbnails/ImageKitThumbnail.php | 2 +- src/Support/Thumbnails/KeyCdnThumbnail.php | 3 +- src/Support/Thumbnails/LocalThumbnail.php | 20 ++- src/View/Components/Content/Attributes.php | 4 +- src/View/Components/File.php | 3 +- tests/ArchTest.php | 1 - tests/Console/ConfigureCmsCommandTest.php | 121 +++++++++--------- tests/Unit/OzuCollectionConfigTest.php | 24 ++-- tests/Unit/OzuCollectionFormConfigTest.php | 36 +++--- tests/Unit/OzuCollectionListConfigTest.php | 23 ++-- tests/Unit/OzuColumnTest.php | 42 +++--- tests/Unit/OzuFieldTest.php | 19 ++- 44 files changed, 288 insertions(+), 258 deletions(-) diff --git a/config/ozu-client.php b/config/ozu-client.php index fcd6afd..19d0475 100644 --- a/config/ozu-client.php +++ b/config/ozu-client.php @@ -13,13 +13,12 @@ // The Ozu unique key of the website to use 'website_key' => env('OZU_WEBSITE_KEY'), - // If you want to use custom storage for your files, you can configure it here. // If you change your configuration after having uploaded files, you will have to manually move them to the new storage // Or reset them in ozu. // This is an example of how to configure a custom S3 storage: - /* 'custom_storage' => OzuCustomS3Storage::make() + /* 'custom_storage' => OzuCustomS3Storage::make() ->setBucketName(env('OZU_S3_BUCKET')) ->setRegion(env('OZU_S3_REGION')) ->setKey(env('OZU_S3_KEY')) diff --git a/database/factories/MediaFactory.php b/database/factories/MediaFactory.php index f026165..9e40f2a 100644 --- a/database/factories/MediaFactory.php +++ b/database/factories/MediaFactory.php @@ -44,17 +44,17 @@ public function file(string $key): Factory }); } - public function withFile(?string $fileName = null, string $type="image") + public function withFile(?string $fileName = null, string $type = 'image') { - return $this->state(function (array $attributes) use ($fileName,$type) { - $fileName = $fileName ?: fake()->slug() . ($type==='image'?'.jpg':'.pdf'); - $path = ($type==="image" ? $this->getRandomFixtureImagePath() : $this->getRandomFixtureDocumentPath()); + return $this->state(function (array $attributes) use ($fileName, $type) { + $fileName = $fileName ?: fake()->slug().($type === 'image' ? '.jpg' : '.pdf'); + $path = ($type === 'image' ? $this->getRandomFixtureImagePath() : $this->getRandomFixtureDocumentPath()); Storage::disk('local') - ->put("/data/".($type==='image'?'medias':'files')."/$fileName", file_get_contents($path)); + ->put('/data/'.($type === 'image' ? 'medias' : 'files')."/$fileName", file_get_contents($path)); return [ - 'file_name' => "data/".($type==='image'?'medias':'files')."/$fileName", + 'file_name' => 'data/'.($type === 'image' ? 'medias' : 'files')."/$fileName", ]; }); } diff --git a/src/Client.php b/src/Client.php index da2c872..94c117b 100644 --- a/src/Client.php +++ b/src/Client.php @@ -12,8 +12,7 @@ public function __construct( protected ?string $apiKey, protected string $apiVersion, protected string $websiteKey, - ) { - } + ) {} public function updateCollectionSharpConfiguration(string $collectionKey, array $collectionData): void { diff --git a/src/Console/ConfigureCmsCommand.php b/src/Console/ConfigureCmsCommand.php index d6801bf..ddcaf87 100644 --- a/src/Console/ConfigureCmsCommand.php +++ b/src/Console/ConfigureCmsCommand.php @@ -5,10 +5,10 @@ use Closure; use Code16\OzuClient\Client; use Code16\OzuClient\OzuCms\Form\OzuField; +use Code16\OzuClient\OzuCms\List\OzuColumn; +use Code16\OzuClient\OzuCms\OzuCollectionConfig; use Code16\OzuClient\OzuCms\OzuCollectionFormConfig; use Code16\OzuClient\OzuCms\OzuCollectionListConfig; -use Code16\OzuClient\OzuCms\OzuCollectionConfig; -use Code16\OzuClient\OzuCms\List\OzuColumn; use Code16\OzuClient\OzuCms\Storage\OzuAbstractCustomStorage; use Illuminate\Console\Command; use Illuminate\Http\Client\RequestException; @@ -17,12 +17,14 @@ class ConfigureCmsCommand extends Command { protected $signature = 'ozu:configure-cms'; + protected $description = 'Send CMS configuration to Ozu.'; public function handle(Client $ozuClient): int { if (empty(config('ozu-client.collections'))) { $this->info('No collections to configure.'); + return self::SUCCESS; } @@ -34,9 +36,9 @@ public function handle(Client $ozuClient): int default => $collection, }; - $collection = $model::configureOzuCollection(new OzuCollectionConfig()); - $list = $model::configureOzuCollectionList(new OzuCollectionListConfig()); - $form = $model::configureOzuCollectionForm(new OzuCollectionFormConfig()); + $collection = $model::configureOzuCollection(new OzuCollectionConfig); + $list = $model::configureOzuCollectionList(new OzuCollectionListConfig); + $form = $model::configureOzuCollectionForm(new OzuCollectionFormConfig); return [ 'key' => $model->ozuCollectionKey(), @@ -46,7 +48,7 @@ public function handle(Client $ozuClient): int 'autoDeployDateField' => $collection->autoDeployDateField(), 'isCreatable' => $collection->isCreatable(), 'isDeletable' => $collection->isDeletable(), - 'order' => $k+1, + 'order' => $k + 1, 'list' => [ 'isReorderable' => $list->isReorderable(), 'isSearchable' => $list->isSearchable(), @@ -60,7 +62,7 @@ public function handle(Client $ozuClient): int 'key' => $column->key(), 'label' => $column->label(), 'size' => $column->size(), - ]) + ]), ], 'form' => [ 'title' => $form->titleField()?->toArray(), @@ -68,46 +70,46 @@ public function handle(Client $ozuClient): int 'content' => $form->contentField()?->toArray(), 'fields' => $form ->customFields() - ->map(fn (OzuField $field) => $field->toArray()) + ->map(fn (OzuField $field) => $field->toArray()), ], 'customFields' => collect(Schema::getColumnListing($model->getTable())) - ->filter(fn (string $column) => !in_array($column, $model::$ozuColumns)) + ->filter(fn (string $column) => ! in_array($column, $model::$ozuColumns)) ->mapWithKeys(fn (string $column) => [ - $column => match(Schema::getColumnType($model->getTable(), $column)) { + $column => match (Schema::getColumnType($model->getTable(), $column)) { 'datetime', 'timestamps' => 'dateTime', 'date' => 'date', 'int', 'bigint', 'smallint', 'mediumint', 'tinyint' => 'integer', 'float', 'double' => 'float', 'text', 'json' => 'text', default => 'string', - } + }, ]), ]; }) ->each(function (array $collection) use ($ozuClient) { - $this->info('Update CMS configuration for [' . $collection['key'] . '].'); - try{ + $this->info('Update CMS configuration for ['.$collection['key'].'].'); + try { $ozuClient->updateCollectionSharpConfiguration( $collection['key'], $collection ); - } catch(RequestException $e) { + } catch (RequestException $e) { if ($message = $e->response->json()) { - if(!isset($message['message'])) { + if (! isset($message['message'])) { throw $e; } - $this->error('[' . $collection['key'] . '] '.$message['message']); + $this->error('['.$collection['key'].'] '.$message['message']); } else { throw $e; } } }); - if(config('ozu-client.custom_storage')) { + if (config('ozu-client.custom_storage')) { $customStorage = config('ozu-client.custom_storage'); - if($customStorage instanceof OzuAbstractCustomStorage) { - if($customStorage->meetRequirements()) { + if ($customStorage instanceof OzuAbstractCustomStorage) { + if ($customStorage->meetRequirements()) { $ozuClient->updateCustomStorageConfiguration(config('ozu-client.custom_storage')->toArray()); } else { $this->error( @@ -115,10 +117,12 @@ public function handle(Client $ozuClient): int $customStorage->whatsMissing()->join(', ') ) ); + return self::FAILURE; } } else { $this->error('Custom storage must be an instance of OzuAbstractCustomStorage'); + return self::FAILURE; } } else { diff --git a/src/Deploy/Crawler/Observer.php b/src/Deploy/Crawler/Observer.php index 469b0e4..2a4122a 100644 --- a/src/Deploy/Crawler/Observer.php +++ b/src/Deploy/Crawler/Observer.php @@ -13,8 +13,8 @@ public function crawled(UriInterface $url, ResponseInterface $response, ?UriInte { try { parent::crawled($url, $response, $foundOnUrl, $linkText); - } catch(\RuntimeException $e) { - if(preg_match('/returned status code \[4\d\d]/', $e->getMessage())) { + } catch (\RuntimeException $e) { + if (preg_match('/returned status code \[4\d\d]/', $e->getMessage())) { Log::warning("Crawled URL {$url} found on {$foundOnUrl} returned status code 4xx", [ 'url' => (string) $url, 'status_code' => $response->getStatusCode(), diff --git a/src/Deploy/DeployServiceProvider.php b/src/Deploy/DeployServiceProvider.php index 380b619..f9e99ee 100644 --- a/src/Deploy/DeployServiceProvider.php +++ b/src/Deploy/DeployServiceProvider.php @@ -18,7 +18,7 @@ public function register() public function boot() { $this->app['events']->listen(function (CommandStarting $event) { - if($event->command === 'export') { + if ($event->command === 'export') { Artisan::call('cache:clear', [], $event->output); } }); diff --git a/src/Deploy/Jobs/CrawlSite.php b/src/Deploy/Jobs/CrawlSite.php index a51e422..5998343 100644 --- a/src/Deploy/Jobs/CrawlSite.php +++ b/src/Deploy/Jobs/CrawlSite.php @@ -1,10 +1,10 @@ setCrawlObserver(new Observer($entry, $destination)) ->setCrawlProfile(new CrawlInternalUrls($entry)) ->startCrawling($entry); diff --git a/src/Deploy/Jobs/CrawlSiteHandler.php b/src/Deploy/Jobs/CrawlSiteHandler.php index 4ee856f..e573b3e 100644 --- a/src/Deploy/Jobs/CrawlSiteHandler.php +++ b/src/Deploy/Jobs/CrawlSiteHandler.php @@ -8,6 +8,6 @@ class CrawlSiteHandler { public function __invoke(): void { - app(Dispatcher::class)->dispatchNow(new CrawlSite()); + app(Dispatcher::class)->dispatchNow(new CrawlSite); } } diff --git a/src/Deploy/Routing/UrlGenerator.php b/src/Deploy/Routing/UrlGenerator.php index 4a5af59..e599f68 100644 --- a/src/Deploy/Routing/UrlGenerator.php +++ b/src/Deploy/Routing/UrlGenerator.php @@ -1,8 +1,8 @@ registerUrlGenerator(); } - public function boot() - { - } + public function boot() {} /** * @see parent::registerUrlGenerator(); diff --git a/src/Eloquent/Media.php b/src/Eloquent/Media.php index df0ecd6..59a7c0b 100644 --- a/src/Eloquent/Media.php +++ b/src/Eloquent/Media.php @@ -3,7 +3,6 @@ namespace Code16\OzuClient\Eloquent; use Code16\OzuClient\Database\Factories\MediaFactory; -use Code16\OzuClient\Support\Thumbnails\LocalThumbnail; use Code16\OzuClient\Support\Thumbnails\Thumbnail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -15,7 +14,9 @@ class Media extends Model use HasFactory; protected $guarded = []; + protected $table = 'medias'; + protected $casts = [ 'custom_properties' => 'array', 'size' => 'integer', @@ -23,7 +24,7 @@ class Media extends Model protected static function newFactory() { - return new MediaFactory(); + return new MediaFactory; } public function model(): MorphTo @@ -31,7 +32,7 @@ public function model(): MorphTo return $this->morphTo('model'); } - public function thumbnail(int $width = null, int $height = null, bool $fit = false): ?string + public function thumbnail(?int $width = null, ?int $height = null, bool $fit = false): ?string { return app(Thumbnail::class) ->forMedia($this) @@ -54,9 +55,9 @@ public function humanReadableSize($precision = 2): ?string if ($this->size >= 0) { $size = (int) $this->size; $base = log($size) / log(1024); - $suffixes = array(' bytes', ' KB', ' MB', ' GB', ' TB'); + $suffixes = [' bytes', ' KB', ' MB', ' GB', ' TB']; - return $this->size === 0 ? '0 bytes' : (round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)]); + return $this->size === 0 ? '0 bytes' : (round(pow(1024, $base - floor($base)), $precision).$suffixes[floor($base)]); } else { return $this->size; } diff --git a/src/OzuCms/Form/OzuBelongsToField.php b/src/OzuCms/Form/OzuBelongsToField.php index c09944f..61247ff 100644 --- a/src/OzuCms/Form/OzuBelongsToField.php +++ b/src/OzuCms/Form/OzuBelongsToField.php @@ -32,4 +32,3 @@ public function toArray(): array ]); } } - diff --git a/src/OzuCms/Form/OzuEditorField.php b/src/OzuCms/Form/OzuEditorField.php index 8eb6a6d..19a3696 100644 --- a/src/OzuCms/Form/OzuEditorField.php +++ b/src/OzuCms/Form/OzuEditorField.php @@ -5,7 +5,9 @@ class OzuEditorField extends OzuField { private bool $withoutParagraphs = false; + private bool $hideToolbar = false; + private array $toolbar = [ OzuEditorToolbarEnum::Bold, OzuEditorToolbarEnum::Italic, @@ -13,7 +15,9 @@ class OzuEditorField extends OzuField OzuEditorToolbarEnum::BulletList, OzuEditorToolbarEnum::Link, ]; + private int $height = 200; + private ?int $maxHeight = null; public function setWithoutParagraphs(): self @@ -37,7 +41,7 @@ public function hideToolbar(): self return $this; } - public function setHeight(int $height, int|null $maxHeight = null): self + public function setHeight(int $height, ?int $maxHeight = null): self { $this->height = $height; $this->maxHeight = $maxHeight; @@ -55,7 +59,7 @@ public function toArray(): array return array_merge(parent::toArray(), [ 'withoutParagraphs' => $this->withoutParagraphs, 'hideToolbar' => $this->hideToolbar, - 'toolbar' => collect($this->toolbar)->map(fn($item) => $item->value)->toArray(), + 'toolbar' => collect($this->toolbar)->map(fn ($item) => $item->value)->toArray(), 'height' => $this->height, 'maxHeight' => $this->maxHeight, ]); diff --git a/src/OzuCms/Form/OzuField.php b/src/OzuCms/Form/OzuField.php index 66ff6b8..de34812 100644 --- a/src/OzuCms/Form/OzuField.php +++ b/src/OzuCms/Form/OzuField.php @@ -5,13 +5,14 @@ abstract class OzuField { protected ?string $label = null; + protected ?string $helpMessage = null; + protected array $validationRules = []; + protected bool $isUpdatable = true; - public function __construct(protected string $key) - { - } + public function __construct(protected string $key) {} public static function makeText(string $key): OzuTextField { diff --git a/src/OzuCms/Form/OzuFileListField.php b/src/OzuCms/Form/OzuFileListField.php index b0bdb8f..fc5f0fa 100644 --- a/src/OzuCms/Form/OzuFileListField.php +++ b/src/OzuCms/Form/OzuFileListField.php @@ -5,7 +5,9 @@ class OzuFileListField extends OzuField { protected int $maxItems = 10; + protected bool $hasLegend = false; + private int $maxFileSizeInMB = 5; public function setMaxItems(int $maxItems): self diff --git a/src/OzuCms/Form/OzuImageField.php b/src/OzuCms/Form/OzuImageField.php index eaaee13..818a10b 100644 --- a/src/OzuCms/Form/OzuImageField.php +++ b/src/OzuCms/Form/OzuImageField.php @@ -5,8 +5,11 @@ class OzuImageField extends OzuField { private array $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; + private int $maxFileSizeInMB = 5; + private bool $hasLegend = false; + private ?string $cropRatio = null; public function setHasLegend(bool $hasLegend = true): self diff --git a/src/OzuCms/Form/OzuSelectField.php b/src/OzuCms/Form/OzuSelectField.php index 6c471f8..6bddd72 100644 --- a/src/OzuCms/Form/OzuSelectField.php +++ b/src/OzuCms/Form/OzuSelectField.php @@ -5,8 +5,11 @@ class OzuSelectField extends OzuField { protected bool $multiple = false; + protected string $display = 'list'; + protected bool $clearable = false; + protected array $options = []; public function setOptions(array $options): self diff --git a/src/OzuCms/List/OzuBelongsToFilter.php b/src/OzuCms/List/OzuBelongsToFilter.php index 0cfa3d0..d5fa288 100644 --- a/src/OzuCms/List/OzuBelongsToFilter.php +++ b/src/OzuCms/List/OzuBelongsToFilter.php @@ -5,11 +5,10 @@ class OzuBelongsToFilter { protected bool $required = true; + private ?string $label = null; - public function __construct(protected string $ozuCollectionKey) - { - } + public function __construct(protected string $ozuCollectionKey) {} public function setRequired(bool $required = true): self { diff --git a/src/OzuCms/List/OzuColumn.php b/src/OzuCms/List/OzuColumn.php index 2f25a5f..3a7e1e2 100644 --- a/src/OzuCms/List/OzuColumn.php +++ b/src/OzuCms/List/OzuColumn.php @@ -5,12 +5,12 @@ abstract class OzuColumn { protected ?string $label = null; + protected bool $isDefaultSort = false; + protected string $sortDirection = 'asc'; - protected function __construct(protected string $key, protected int $size) - { - } + protected function __construct(protected string $key, protected int $size) {} public static function makeText(string $key, int $size): OzuTextColumn { diff --git a/src/OzuCms/List/OzuDateColumn.php b/src/OzuCms/List/OzuDateColumn.php index 8adcdb4..98f20a1 100644 --- a/src/OzuCms/List/OzuDateColumn.php +++ b/src/OzuCms/List/OzuDateColumn.php @@ -2,8 +2,6 @@ namespace Code16\OzuClient\OzuCms\List; -use Carbon\Carbon; - class OzuDateColumn extends OzuColumn { public function type(): string diff --git a/src/OzuCms/OzuCollectionConfig.php b/src/OzuCms/OzuCollectionConfig.php index 2f59174..09d188e 100644 --- a/src/OzuCms/OzuCollectionConfig.php +++ b/src/OzuCms/OzuCollectionConfig.php @@ -5,11 +5,15 @@ class OzuCollectionConfig { protected string $label; + protected string $icon; + protected bool $hasPublicationState = false; protected ?string $autoDeployDateField = null; + private bool $isCreatable = true; + private bool $isDeletable = true; public function setLabel(string $label): self @@ -35,7 +39,8 @@ public function setHasPublicationState(bool $hasState = true): self /** * Declare which date field will trigger auto-deploy when reached - * @param string|null $field + * + * @param string|null $field * @return $this */ public function setAutoDeployDateField(string $fieldKey): self @@ -76,7 +81,7 @@ public function hasPublicationState(): bool public function hasAutoDeployDateField(): bool { - return !is_null($this->autoDeployDateField); + return ! is_null($this->autoDeployDateField); } public function autoDeployDateField(): ?string diff --git a/src/OzuCms/OzuCollectionFormConfig.php b/src/OzuCms/OzuCollectionFormConfig.php index 52b1a93..948f8ee 100644 --- a/src/OzuCms/OzuCollectionFormConfig.php +++ b/src/OzuCms/OzuCollectionFormConfig.php @@ -14,15 +14,19 @@ class OzuCollectionFormConfig { protected ?OzuTextField $titleField; + protected bool $hideTitleField = false; protected ?OzuImageField $coverField; + protected bool $hideCoverField = false; protected ?OzuEditorField $contentField; + protected bool $hideContentField = false; protected array $fields = []; + protected ?OzuBelongsToField $belongsToField = null; public function addCustomField(OzuField $field): self @@ -89,7 +93,7 @@ public function declareBelongsToField(string $ozuModelClass, string $label, bool $this->belongsToField = (new OzuBelongsToField($ozuCollectionKey)) ->setLabel($label) - ->setClearable(!$required) + ->setClearable(! $required) ->setValidationRules($required ? ['required'] : []); return $this; @@ -100,7 +104,7 @@ public function customFields(): Collection return collect( [ $this->belongsToField, - ...$this->fields + ...$this->fields, ]) ->whereNotNull() ->values(); @@ -112,7 +116,7 @@ public function titleField(): ?OzuTextField return null; } - if (!isset($this->titleField)) { + if (! isset($this->titleField)) { $this->titleField = OzuField::makeText('title'); } @@ -125,7 +129,7 @@ public function coverField(): ?OzuImageField return null; } - if (!isset($this->coverField)) { + if (! isset($this->coverField)) { $this->coverField = OzuField::makeImage('cover') ->setMaxFileSizeInMB(3); } @@ -139,7 +143,7 @@ public function contentField(): ?OzuEditorField return null; } - if (!isset($this->contentField)) { + if (! isset($this->contentField)) { $this->contentField = OzuField::makeEditor('content') ->setToolbar([ OzuEditorToolbarEnum::Bold, diff --git a/src/OzuCms/OzuCollectionListConfig.php b/src/OzuCms/OzuCollectionListConfig.php index a21d4af..957288f 100644 --- a/src/OzuCms/OzuCollectionListConfig.php +++ b/src/OzuCms/OzuCollectionListConfig.php @@ -2,7 +2,6 @@ namespace Code16\OzuClient\OzuCms; -use Code16\OzuClient\OzuCms\Form\OzuBelongsToField; use Code16\OzuClient\OzuCms\List\OzuBelongsToFilter; use Code16\OzuClient\OzuCms\List\OzuColumn; use Illuminate\Support\Collection; @@ -10,10 +9,13 @@ class OzuCollectionListConfig { protected bool $isReorderable = false; + protected bool $isSearchable = false; + protected bool $isPaginated = false; protected ?OzuBelongsToFilter $belongsToFilter = null; + protected array $columns = []; public function setIsReorderable(bool $isReorderable = true): self diff --git a/src/OzuCms/Storage/OzuAbstractCustomStorage.php b/src/OzuCms/Storage/OzuAbstractCustomStorage.php index 048dcb1..5fd28b9 100644 --- a/src/OzuCms/Storage/OzuAbstractCustomStorage.php +++ b/src/OzuCms/Storage/OzuAbstractCustomStorage.php @@ -8,12 +8,12 @@ abstract class OzuAbstractCustomStorage { public static function make(): self { - return new static(); + return new static; } - public abstract function meetRequirements(): bool; + abstract public function meetRequirements(): bool; - public abstract function whatsMissing(): Collection; + abstract public function whatsMissing(): Collection; - public abstract function toArray(): array; + abstract public function toArray(): array; } diff --git a/src/OzuCms/Storage/OzuCustomFTPStorage.php b/src/OzuCms/Storage/OzuCustomFTPStorage.php index 5b0bf98..49b9ee9 100644 --- a/src/OzuCms/Storage/OzuCustomFTPStorage.php +++ b/src/OzuCms/Storage/OzuCustomFTPStorage.php @@ -8,12 +8,19 @@ class OzuCustomFTPStorage extends OzuAbstractCustomStorage { protected $host = null; + protected $username = null; + protected $password = null; + protected $port = 21; + protected $root = '/'; + protected $passive = true; + protected $ssl = true; + protected $timeout = 5; public function setHost(string $host): self @@ -67,8 +74,7 @@ public function setSsl(bool $ssl): self public function setTimeout(int $timeout): self { - if($timeout > 30) - { + if ($timeout > 30) { throw new Exception('Timeout must be less than 30 seconds'); } @@ -94,8 +100,7 @@ public function toArray(): array public function meetRequirements(): bool { - if(!$this->host || !$this->username || !$this->password) - { + if (! $this->host || ! $this->username || ! $this->password) { return false; } @@ -105,9 +110,9 @@ public function meetRequirements(): bool public function whatsMissing(): Collection { return collect([ - !$this->host ? 'Host' : null, - !$this->username ? 'Username' : null, - !$this->password ? 'Password' : null, + ! $this->host ? 'Host' : null, + ! $this->username ? 'Username' : null, + ! $this->password ? 'Password' : null, ])->filter(); } } diff --git a/src/OzuCms/Storage/OzuCustomS3Storage.php b/src/OzuCms/Storage/OzuCustomS3Storage.php index bfc191a..78b622a 100644 --- a/src/OzuCms/Storage/OzuCustomS3Storage.php +++ b/src/OzuCms/Storage/OzuCustomS3Storage.php @@ -7,10 +7,15 @@ class OzuCustomS3Storage extends OzuAbstractCustomStorage { protected $bucket = null; + protected $region = null; + protected $key = null; + protected $secret = null; + protected $endpoint = null; + protected $use_path_style_endpoint = false; public function setBucketName(string $bucket): self @@ -70,8 +75,7 @@ public function toArray(): array public function meetRequirements(): bool { - if(!$this->bucket || !$this->region || !$this->key || !$this->secret || !$this->endpoint) - { + if (! $this->bucket || ! $this->region || ! $this->key || ! $this->secret || ! $this->endpoint) { return false; } @@ -81,11 +85,11 @@ public function meetRequirements(): bool public function whatsMissing(): Collection { return collect([ - !$this->bucket ? 'Host' : null, - !$this->region ? 'Region' : null, - !$this->key ? 'Key' : null, - !$this->secret ? 'Secret' : null, - !$this->endpoint ? 'Endpoint' : null, + ! $this->bucket ? 'Host' : null, + ! $this->region ? 'Region' : null, + ! $this->key ? 'Key' : null, + ! $this->secret ? 'Secret' : null, + ! $this->endpoint ? 'Endpoint' : null, ])->filter(); } } diff --git a/src/OzuServiceProvider.php b/src/OzuServiceProvider.php index 2fab160..63f08e0 100644 --- a/src/OzuServiceProvider.php +++ b/src/OzuServiceProvider.php @@ -49,11 +49,11 @@ public function register() $this->app->bind(Paginator::class, StaticPaginator::class); $this->app->bind(LengthAwarePaginator::class, StaticLengthAwarePaginator::class); $this->app->bind(Thumbnail::class, function ($app) { - if (!$app->environment(['local', 'testing']) && config('ozu-client.custom_storage')) { + if (! $app->environment(['local', 'testing']) && config('ozu-client.custom_storage')) { return $app->make(CustomStorageThumbnail::class); } - if (!$app->environment('production') || !config('ozu-client.cdn_url')) { + if (! $app->environment('production') || ! config('ozu-client.cdn_url')) { return $app->make(LocalThumbnail::class); } @@ -93,7 +93,7 @@ public function boot() Relation::enforceMorphMap( collect(config('ozu-client.collections')) ->mapWithKeys(fn (string $className) => [ - (new $className)->ozuCollectionKey() => $className + (new $className)->ozuCollectionKey() => $className, ]) ->toArray() ); diff --git a/src/Support/Database/OzuSeeder.php b/src/Support/Database/OzuSeeder.php index ff00cb8..1fd4d59 100644 --- a/src/Support/Database/OzuSeeder.php +++ b/src/Support/Database/OzuSeeder.php @@ -12,8 +12,8 @@ protected function clearMediaDirectory(): void if (file_exists($mediaDirectory)) { collect(scandir($mediaDirectory)) - ->filter(fn ($file) => !in_array($file, ['.', '..'])) - ->each(fn ($file) => unlink($mediaDirectory . '/' . $file)); + ->filter(fn ($file) => ! in_array($file, ['.', '..'])) + ->each(fn ($file) => unlink($mediaDirectory.'/'.$file)); } } } diff --git a/src/Support/Image.php b/src/Support/Image.php index 4b6007e..8a18717 100644 --- a/src/Support/Image.php +++ b/src/Support/Image.php @@ -7,12 +7,11 @@ class Image public function __construct( public string $src, public ?string $legend, - ) { - } + ) {} public static function make(string|array $data): static { - if(is_string($data)) { + if (is_string($data)) { return new static($data, null); } @@ -30,10 +29,10 @@ public function thumbnail(?int $width = null, ?int $height = null, ?float $scale $height = $height ? $height * $scale : null; // https://docs.imagekit.io/features/image-transformations/resize-crop-and-other-transformations - return $this->src . '?tr=' . implode(',', array_keys(array_filter([ + return $this->src.'?tr='.implode(',', array_keys(array_filter([ "w-$width" => $width, "h-$height" => $height, - "c-at_max" => !$crop, + 'c-at_max' => ! $crop, ]))); } diff --git a/src/Support/ImageCollection.php b/src/Support/ImageCollection.php index bed23d0..7d876bb 100644 --- a/src/Support/ImageCollection.php +++ b/src/Support/ImageCollection.php @@ -7,6 +7,4 @@ /** * @implements Collection */ -class ImageCollection extends Collection -{ -} +class ImageCollection extends Collection {} diff --git a/src/Support/Thumbnails/CdnThumbnail.php b/src/Support/Thumbnails/CdnThumbnail.php index 1e753e4..2a53ce3 100644 --- a/src/Support/Thumbnails/CdnThumbnail.php +++ b/src/Support/Thumbnails/CdnThumbnail.php @@ -6,7 +6,7 @@ abstract class CdnThumbnail extends Thumbnail { public function make(?int $width, ?int $height = null, bool $fit = false): ?string { - if($cdnUrl = str(config('ozu-client.cdn_url'))->rtrim('/')) { + if ($cdnUrl = str(config('ozu-client.cdn_url'))->rtrim('/')) { return sprintf( '%s/storage/%s?%s', $cdnUrl, @@ -22,7 +22,7 @@ abstract protected function generateUrlParameters(?int $width, ?int $height, boo public function download(): ?string { - if($cdnUrl = str(config('ozu-client.cdn_url'))->rtrim('/')) { + if ($cdnUrl = str(config('ozu-client.cdn_url'))->rtrim('/')) { return sprintf( '%s/storage/%s', $cdnUrl, diff --git a/src/Support/Thumbnails/CustomStorageThumbnail.php b/src/Support/Thumbnails/CustomStorageThumbnail.php index 4656b15..9ed55cf 100644 --- a/src/Support/Thumbnails/CustomStorageThumbnail.php +++ b/src/Support/Thumbnails/CustomStorageThumbnail.php @@ -14,16 +14,22 @@ class CustomStorageThumbnail extends Thumbnail { protected ImageManager $imageManager; + protected FilesystemManager $storage; + protected int $quality = 90; + protected ?int $width; + protected ?int $height; + protected bool $fit; + protected bool $appendTimestamp = true; public function __construct() { - $this->imageManager = new ImageManager(new Driver()); + $this->imageManager = new ImageManager(new Driver); $this->storage = app(FilesystemManager::class); } @@ -63,7 +69,7 @@ private function generateThumbnail(string $sourceDisk, string $sourceRelPath, st $sourceDisk = config('ozu-client.custom_storage') ? 'custom' : $sourceDisk; - if (!$thumbnailDisk->exists($thumbnailPath)) { + if (! $thumbnailDisk->exists($thumbnailPath)) { // Create thumbnail directories if needed if (! $thumbnailDisk->exists(dirname($thumbnailPath))) { $thumbnailDisk->makeDirectory(dirname($thumbnailPath)); @@ -96,25 +102,24 @@ public function download(): ?string { $filesDisk = $this->storage->disk('public'); - if (!$filesDisk->exists($this->mediaModel->file_name)) { + if (! $filesDisk->exists($this->mediaModel->file_name)) { // Create files directories if needed - if (!$filesDisk->exists(dirname($this->mediaModel->file_name))) { + if (! $filesDisk->exists(dirname($this->mediaModel->file_name))) { $filesDisk->makeDirectory(dirname($this->mediaModel->file_name)); } - try{ - if(config('ozu-client.custom_storage')) - { + try { + if (config('ozu-client.custom_storage')) { $filesDisk->put($this->mediaModel->file_name, $this->storage->build(config('ozu-client.custom_storage')->toArray())->get($this->mediaModel->file_name)); } else { $filesDisk->put($this->mediaModel->file_name, $this->storage->disk($this->mediaModel->disk)->get($this->mediaModel->file_name)); } - }catch (BindingResolutionException|CircularDependencyException|FileNotFoundException|DecoderException) { + } catch (BindingResolutionException|CircularDependencyException|FileNotFoundException|DecoderException) { return null; } } - return $this->storage->disk("public")->url($this->mediaModel->file_name); + return $this->storage->disk('public')->url($this->mediaModel->file_name); } } diff --git a/src/Support/Thumbnails/ImageKitThumbnail.php b/src/Support/Thumbnails/ImageKitThumbnail.php index 755e077..5c4d142 100644 --- a/src/Support/Thumbnails/ImageKitThumbnail.php +++ b/src/Support/Thumbnails/ImageKitThumbnail.php @@ -6,7 +6,7 @@ class ImageKitThumbnail extends CdnThumbnail { protected function generateUrlParameters(?int $width, ?int $height, bool $fit): string { - if (!$fit) { + if (! $fit) { if ($width && $height) { return sprintf('tr=w-%s,h-%s,c-at_max', $width, $height); } diff --git a/src/Support/Thumbnails/KeyCdnThumbnail.php b/src/Support/Thumbnails/KeyCdnThumbnail.php index 9f4d9fe..ce43f81 100644 --- a/src/Support/Thumbnails/KeyCdnThumbnail.php +++ b/src/Support/Thumbnails/KeyCdnThumbnail.php @@ -4,10 +4,9 @@ class KeyCdnThumbnail extends CdnThumbnail { - protected function generateUrlParameters(?int $width, ?int $height, bool $fit): string { - if (!$fit) { + if (! $fit) { if ($width && $height) { return sprintf('width=%s&height=%s&fit=inside', $width, $height); } diff --git a/src/Support/Thumbnails/LocalThumbnail.php b/src/Support/Thumbnails/LocalThumbnail.php index e871e55..c422d75 100644 --- a/src/Support/Thumbnails/LocalThumbnail.php +++ b/src/Support/Thumbnails/LocalThumbnail.php @@ -12,16 +12,22 @@ class LocalThumbnail extends Thumbnail { protected ImageManager $imageManager; + protected FilesystemManager $storage; + protected int $quality = 90; + protected ?int $width; + protected ?int $height; + protected bool $fit; + protected bool $appendTimestamp = true; public function __construct() { - $this->imageManager = new ImageManager(new Driver()); + $this->imageManager = new ImageManager(new Driver); $this->storage = app(FilesystemManager::class); } @@ -59,7 +65,7 @@ private function generateThumbnail(string $sourceDisk, string $sourceRelPath, st { $thumbnailDisk = $this->storage->disk('public'); - if (!$thumbnailDisk->exists($thumbnailPath)) { + if (! $thumbnailDisk->exists($thumbnailPath)) { // Create thumbnail directories if needed if (! $thumbnailDisk->exists(dirname($thumbnailPath))) { $thumbnailDisk->makeDirectory(dirname($thumbnailPath)); @@ -90,19 +96,19 @@ public function download(): ?string { $filesDisk = $this->storage->disk('public'); - if (!$filesDisk->exists($this->mediaModel->file_name)) { + if (! $filesDisk->exists($this->mediaModel->file_name)) { // Create files directories if needed - if (!$filesDisk->exists(dirname($this->mediaModel->file_name))) { + if (! $filesDisk->exists(dirname($this->mediaModel->file_name))) { $filesDisk->makeDirectory(dirname($this->mediaModel->file_name)); } - try{ + try { $filesDisk->put($this->mediaModel->file_name, $this->storage->disk($this->mediaModel->disk)->get($this->mediaModel->file_name)); - }catch (FileNotFoundException|DecoderException) { + } catch (FileNotFoundException|DecoderException) { return null; } } - return $this->storage->disk("public")->url($this->mediaModel->file_name); + return $this->storage->disk('public')->url($this->mediaModel->file_name); } } diff --git a/src/View/Components/Content/Attributes.php b/src/View/Components/Content/Attributes.php index d9a7254..54be1ef 100644 --- a/src/View/Components/Content/Attributes.php +++ b/src/View/Components/Content/Attributes.php @@ -4,6 +4,4 @@ use Code16\ContentRenderer\View\Components\Attributes as AttributesComponent; -class Attributes extends AttributesComponent -{ -} +class Attributes extends AttributesComponent {} diff --git a/src/View/Components/File.php b/src/View/Components/File.php index e046ddb..d534779 100644 --- a/src/View/Components/File.php +++ b/src/View/Components/File.php @@ -10,8 +10,7 @@ class File extends Component public function __construct( public string $name, public string $href, - ) { - } + ) {} public function render(): View { diff --git a/tests/ArchTest.php b/tests/ArchTest.php index bac1874..c879a5b 100644 --- a/tests/ArchTest.php +++ b/tests/ArchTest.php @@ -3,4 +3,3 @@ it('will not use debugging functions') ->expect(['die', 'dd', 'dump', 'ray', 'ddRawSql', 'var_dump']) ->each->not->toBeUsed(); - diff --git a/tests/Console/ConfigureCmsCommandTest.php b/tests/Console/ConfigureCmsCommandTest.php index 6356d3b..9901996 100644 --- a/tests/Console/ConfigureCmsCommandTest.php +++ b/tests/Console/ConfigureCmsCommandTest.php @@ -7,7 +7,7 @@ use Code16\OzuClient\OzuCms\OzuCollectionListConfig; use Code16\OzuClient\Tests\Fixtures\DummyTestModel; use Illuminate\Console\Command; -use \Illuminate\Http\Client\Request; +use Illuminate\Http\Client\Request; beforeEach(function () { config(['ozu-client.website_key' => 'test']); @@ -16,18 +16,20 @@ it('sends cms configuration to Ozu for each configured collection', function () { config(['ozu-client.collections' => [ - new class extends DummyTestModel { + new class extends DummyTestModel + { public function ozuCollectionKey(): string { return 'dummy1'; } }, - new class extends DummyTestModel { + new class extends DummyTestModel + { public function ozuCollectionKey(): string { return 'dummy2'; } - } + }, ]]); $this->artisan('ozu:configure-cms') @@ -36,22 +38,22 @@ public function ozuCollectionKey(): string Http::assertSent(function (Request $request) { return $request->url() == sprintf( - '%s/api/%s/%s/collections/%s/configure', - rtrim(config('ozu-client.api_host'), '/'), - config('ozu-client.api_version'), - 'test', - 'dummy1' - ); + '%s/api/%s/%s/collections/%s/configure', + rtrim(config('ozu-client.api_host'), '/'), + config('ozu-client.api_version'), + 'test', + 'dummy1' + ); }); Http::assertSent(function (Request $request) { return $request->url() == sprintf( - '%s/api/%s/%s/collections/%s/configure', - rtrim(config('ozu-client.api_host'), '/'), - config('ozu-client.api_version'), - 'test', - 'dummy2' - ); + '%s/api/%s/%s/collections/%s/configure', + rtrim(config('ozu-client.api_host'), '/'), + config('ozu-client.api_version'), + 'test', + 'dummy2' + ); }); }); @@ -59,7 +61,8 @@ public function ozuCollectionKey(): string Http::fake(); config(['ozu-client.collections' => [ - new class extends DummyTestModel { + new class extends DummyTestModel + { public function ozuCollectionKey(): string { return 'dummy'; @@ -75,7 +78,7 @@ public static function configureOzuCollection(OzuCollectionConfig $config ->setIsCreatable() ->setIsDeletable(); } - } + }, ]]); $this->artisan('ozu:configure-cms') @@ -84,12 +87,12 @@ public static function configureOzuCollection(OzuCollectionConfig $config Http::assertSent(function (Request $request) { return $request->url() == sprintf( - '%s/api/%s/%s/collections/%s/configure', - rtrim(config('ozu-client.api_host'), '/'), - config('ozu-client.api_version'), - 'test', - 'dummy' - ) + '%s/api/%s/%s/collections/%s/configure', + rtrim(config('ozu-client.api_host'), '/'), + config('ozu-client.api_version'), + 'test', + 'dummy' + ) && $request['label'] == 'Dummy label' && $request['icon'] == 'dummy-icon' && $request['hasPublicationState'] == true @@ -103,7 +106,8 @@ public static function configureOzuCollection(OzuCollectionConfig $config Http::fake(); config(['ozu-client.collections' => [ - new class extends DummyTestModel { + new class extends DummyTestModel + { public function ozuCollectionKey(): string { return 'dummy'; @@ -120,7 +124,7 @@ public static function configureOzuCollectionList(OzuCollectionListConfig $confi ->addColumn(OzuColumn::makeImage('dummy-image', 3)->setLabel('Dummy image')) ->addColumn(OzuColumn::makeDate('dummy-date', 3)->setLabel('Dummy date')->setDefaultSort()); } - } + }, ]]); $this->artisan('ozu:configure-cms') @@ -137,26 +141,26 @@ public static function configureOzuCollectionList(OzuCollectionListConfig $confi 'type' => 'text', 'key' => 'dummy-text', 'label' => 'Dummy text', - 'size' => 1 + 'size' => 1, ], [ 'type' => 'check', 'key' => 'dummy-check', 'label' => 'Dummy check', - 'size' => 2 + 'size' => 2, ], [ 'type' => 'image', 'key' => 'dummy-image', 'label' => 'Dummy image', - 'size' => 3 + 'size' => 3, ], [ 'type' => 'date', 'key' => 'dummy-date', 'label' => 'Dummy date', - 'size' => 3 - ] + 'size' => 3, + ], ]); }); }); @@ -165,7 +169,8 @@ public static function configureOzuCollectionList(OzuCollectionListConfig $confi Http::fake(); config(['ozu-client.collections' => [ - new class extends DummyTestModel { + new class extends DummyTestModel + { public function ozuCollectionKey(): string { return 'dummy'; @@ -182,12 +187,12 @@ public static function configureOzuCollectionForm(OzuCollectionFormConfig $confi ->addCustomField( OzuField::makeSelect('dummy-select') ->setDisplayAsDropdown() - ->setOptions([1 =>'option1', 2 => 'option2']) + ->setOptions([1 => 'option1', 2 => 'option2']) ->setLabel('Dummy select') ->setHelpMessage('Select an option') ); } - } + }, ]]); $this->artisan('ozu:configure-cms') @@ -196,27 +201,27 @@ public static function configureOzuCollectionForm(OzuCollectionFormConfig $confi Http::assertSent(function (Request $request) { return $request['form']['fields'] == collect([ - [ - 'type' => 'text', - 'key' => 'dummy-text', - 'label' => 'Dummy text', - 'validationRules' => ['required'], - 'helpMessage' => null, - 'isUpdatable' => true, - ], - [ - 'type' => 'select', - 'key' => 'dummy-select', - 'label' => 'Dummy select', - 'options' => [1 =>'option1', 2 => 'option2'], - 'multiple' => false, - 'display' => 'dropdown', - 'clearable' => false, - 'validationRules' => [], - 'helpMessage' => 'Select an option', - 'isUpdatable' => true, - ], - ]); + [ + 'type' => 'text', + 'key' => 'dummy-text', + 'label' => 'Dummy text', + 'validationRules' => ['required'], + 'helpMessage' => null, + 'isUpdatable' => true, + ], + [ + 'type' => 'select', + 'key' => 'dummy-select', + 'label' => 'Dummy select', + 'options' => [1 => 'option1', 2 => 'option2'], + 'multiple' => false, + 'display' => 'dropdown', + 'clearable' => false, + 'validationRules' => [], + 'helpMessage' => 'Select an option', + 'isUpdatable' => true, + ], + ]); }); }); @@ -237,12 +242,13 @@ public static function configureOzuCollectionForm(OzuCollectionFormConfig $confi ); config(['ozu-client.collections' => [ - new class extends DummyTestModel { + new class extends DummyTestModel + { public function ozuCollectionKey(): string { return 'dummy'; } - } + }, ]]); $this->artisan('ozu:configure-cms') @@ -255,4 +261,3 @@ public function ozuCollectionKey(): string ]); }); }); - diff --git a/tests/Unit/OzuCollectionConfigTest.php b/tests/Unit/OzuCollectionConfigTest.php index 9f3fe2a..610224b 100644 --- a/tests/Unit/OzuCollectionConfigTest.php +++ b/tests/Unit/OzuCollectionConfigTest.php @@ -2,8 +2,8 @@ use Code16\OzuClient\OzuCms\OzuCollectionConfig; -it('set defauls config values', function() { - $ozuCollectionConfig = new OzuCollectionConfig(); +it('set defauls config values', function () { + $ozuCollectionConfig = new OzuCollectionConfig; expect($ozuCollectionConfig->label())->toBe('no label')->and($ozuCollectionConfig->icon())->toBeNull() ->and($ozuCollectionConfig->hasPublicationState())->toBeFalse() @@ -16,7 +16,7 @@ 'hasPublicationState', 'autoDeployDateField', 'isCreatable', - 'isDeletable' + 'isDeletable', ]) ->and($ozuCollectionConfig)->toHaveMethods([ 'setLabel', @@ -31,13 +31,13 @@ 'autoDeployDateField', 'hasAutoDeployDateField', 'isCreatable', - 'isDeletable' + 'isDeletable', ]); }); -it('allows to set label and icon', function() { - $ozuCollectionConfig = new OzuCollectionConfig(); +it('allows to set label and icon', function () { + $ozuCollectionConfig = new OzuCollectionConfig; $ozuCollectionConfig ->setLabel('label') @@ -47,8 +47,8 @@ ->and($ozuCollectionConfig->icon())->toBe('icon'); }); -it('allows to set hasPublicationState and setAutoDeployField', function() { - $ozuCollectionConfig = new OzuCollectionConfig(); +it('allows to set hasPublicationState and setAutoDeployField', function () { + $ozuCollectionConfig = new OzuCollectionConfig; $ozuCollectionConfig->setHasPublicationState(); $ozuCollectionConfig->setAutoDeployDateField('date'); @@ -57,8 +57,8 @@ ->and($ozuCollectionConfig->autoDeployDateField())->toBe('date'); }); -it('allows to set isCreatable and isDeletable', function() { - $ozuCollectionConfig = new OzuCollectionConfig(); +it('allows to set isCreatable and isDeletable', function () { + $ozuCollectionConfig = new OzuCollectionConfig; $ozuCollectionConfig->setIsCreatable(false); $ozuCollectionConfig->setIsDeletable(false); @@ -67,8 +67,8 @@ ->and($ozuCollectionConfig->isDeletable())->toBeFalse(); }); -it('allows to chain methods', function() { - $ozuCollectionConfig = new OzuCollectionConfig(); +it('allows to chain methods', function () { + $ozuCollectionConfig = new OzuCollectionConfig; $ozuCollectionConfig ->setLabel('label') diff --git a/tests/Unit/OzuCollectionFormConfigTest.php b/tests/Unit/OzuCollectionFormConfigTest.php index cf7cf4a..ae93d40 100644 --- a/tests/Unit/OzuCollectionFormConfigTest.php +++ b/tests/Unit/OzuCollectionFormConfigTest.php @@ -7,9 +7,8 @@ use Code16\OzuClient\OzuCms\Form\OzuTextField; use Code16\OzuClient\OzuCms\OzuCollectionFormConfig; -it("set default form values", function() { - $ozuCollectionFormConfig = new OzuCollectionFormConfig(); - +it('set default form values', function () { + $ozuCollectionFormConfig = new OzuCollectionFormConfig; expect($ozuCollectionFormConfig->customFields())->toBeEmpty() ->and($ozuCollectionFormConfig->titleField())->toBeInstanceOf(OzuTextField::class) @@ -26,7 +25,7 @@ 'contentField', 'hideContentField', 'fields', - 'belongsToField' + 'belongsToField', ]) ->and($ozuCollectionFormConfig)->toHaveMethods([ 'addCustomField', @@ -40,12 +39,12 @@ 'customFields', 'titleField', 'coverField', - 'contentField' + 'contentField', ]); }); -it("allows to add custom fields", function() { - $ozuCollectionFormConfig = new OzuCollectionFormConfig(); +it('allows to add custom fields', function () { + $ozuCollectionFormConfig = new OzuCollectionFormConfig; $ozuCollectionFormConfig ->addCustomField(OzuField::makeText('text')) @@ -58,22 +57,22 @@ ->and($ozuCollectionFormConfig->customFields()[1]?->toArray()['key'])->toBe('image'); }); -it("allows to configure title field", function() { - $ozuCollectionFormConfig = new OzuCollectionFormConfig(); +it('allows to configure title field', function () { + $ozuCollectionFormConfig = new OzuCollectionFormConfig; $ozuCollectionFormConfig - ->configureTitleField(function($field) { + ->configureTitleField(function ($field) { $field->setLabel('new label'); }); expect($ozuCollectionFormConfig->titleField()->toArray()['label'])->toBe('new label'); }); -it("allows to configure cover field", function() { - $ozuCollectionFormConfig = new OzuCollectionFormConfig(); +it('allows to configure cover field', function () { + $ozuCollectionFormConfig = new OzuCollectionFormConfig; $ozuCollectionFormConfig - ->configureCoverField(function($field) { + ->configureCoverField(function ($field) { $field->setMaxFileSizeInMB(50) ->setHasLegend(); }); @@ -82,11 +81,11 @@ ->and($ozuCollectionFormConfig->coverField()->toArray()['hasLegend'])->toBeTrue(); }); -it("allows to configure content field", function() { - $ozuCollectionFormConfig = new OzuCollectionFormConfig(); +it('allows to configure content field', function () { + $ozuCollectionFormConfig = new OzuCollectionFormConfig; $ozuCollectionFormConfig - ->configureContentField(function($field) { + ->configureContentField(function ($field) { $field->setHeight(100, 200) ->setToolbar([ OzuEditorToolbarEnum::Bold, @@ -105,8 +104,8 @@ }); -it("allows to hide title, cover and content fields", function() { - $ozuCollectionFormConfig = new OzuCollectionFormConfig(); +it('allows to hide title, cover and content fields', function () { + $ozuCollectionFormConfig = new OzuCollectionFormConfig; $ozuCollectionFormConfig ->hideTitleField() @@ -117,4 +116,3 @@ ->and($ozuCollectionFormConfig->coverField())->toBeNull() ->and($ozuCollectionFormConfig->contentField())->toBeNull(); }); - diff --git a/tests/Unit/OzuCollectionListConfigTest.php b/tests/Unit/OzuCollectionListConfigTest.php index 09b0f34..6a1aa2e 100644 --- a/tests/Unit/OzuCollectionListConfigTest.php +++ b/tests/Unit/OzuCollectionListConfigTest.php @@ -6,10 +6,9 @@ use Code16\OzuClient\OzuCms\List\OzuThumbnailColumn; use Code16\OzuClient\OzuCms\OzuCollectionListConfig; use Code16\OzuClient\Tests\Fixtures\DummyTestModel; -use Illuminate\Database\Eloquent\Model; -it('set defauls config values', function() { - $ozuCollectionListConfig = new OzuCollectionListConfig(); +it('set defauls config values', function () { + $ozuCollectionListConfig = new OzuCollectionListConfig; expect($ozuCollectionListConfig->isReorderable())->toBeFalse() ->and($ozuCollectionListConfig->isPaginated())->toBeFalse() @@ -38,8 +37,8 @@ ]); }); -it('allows to set isReorderable, isSearchable and isPaginated', function() { - $ozuCollectionListConfig = new OzuCollectionListConfig(); +it('allows to set isReorderable, isSearchable and isPaginated', function () { + $ozuCollectionListConfig = new OzuCollectionListConfig; $ozuCollectionListConfig ->setIsReorderable() @@ -51,8 +50,8 @@ ->and($ozuCollectionListConfig->isPaginated())->toBeTrue(); }); -it('allows to declare belongsToFilter', function() { - $ozuCollectionListConfig = new OzuCollectionListConfig(); +it('allows to declare belongsToFilter', function () { + $ozuCollectionListConfig = new OzuCollectionListConfig; $ozuCollectionListConfig->declareBelongsToFilter(DummyTestModel::class, 'label'); @@ -62,8 +61,8 @@ ->and($ozuCollectionListConfig->belongsToFilter()->toArray()['required'])->toBeTrue(); }); -it('allows to add columns', function() { - $ozuCollectionListConfig = new OzuCollectionListConfig(); +it('allows to add columns', function () { + $ozuCollectionListConfig = new OzuCollectionListConfig; $ozuCollectionListConfig ->addColumn(OzuColumn::makeText('text', 1)) @@ -78,8 +77,8 @@ ->and($ozuCollectionListConfig->columns()[1]->size())->toBe(3); }); -it('allows to set defaultSort', function() { - $ozuCollectionListConfig = new OzuCollectionListConfig(); +it('allows to set defaultSort', function () { + $ozuCollectionListConfig = new OzuCollectionListConfig; $ozuCollectionListConfig ->addColumn(OzuColumn::makeText('text', 1)->setDefaultSort('desc')); @@ -89,5 +88,3 @@ 'direction' => 'desc', ]); }); - - diff --git a/tests/Unit/OzuColumnTest.php b/tests/Unit/OzuColumnTest.php index 9c7b22f..115eaeb 100644 --- a/tests/Unit/OzuColumnTest.php +++ b/tests/Unit/OzuColumnTest.php @@ -2,56 +2,54 @@ use Code16\OzuClient\OzuCms\List\OzuColumn; -it('sets default text values', function() { - $ozuColumn = OzuColumn::makeText('key', 1); +it('sets default text values', function () { + $ozuColumn = OzuColumn::makeText('key', 1); - expect($ozuColumn->type())->toBe("text") - ->and($ozuColumn->key())->toBe("key") - ->and($ozuColumn->size())->toBe(1) - ->and($ozuColumn->label())->toBeNull(); + expect($ozuColumn->type())->toBe('text') + ->and($ozuColumn->key())->toBe('key') + ->and($ozuColumn->size())->toBe(1) + ->and($ozuColumn->label())->toBeNull(); }); -it('allows to use setLabel and setDefaultSort', function() { +it('allows to use setLabel and setDefaultSort', function () { $ozuColumn = OzuColumn::makeText('key', 1) ->setLabel('label') ->setDefaultSort('desc'); - expect($ozuColumn->label())->toBe("label") - ->and($ozuColumn->getDefaultSortDirection())->toBe("desc"); + expect($ozuColumn->label())->toBe('label') + ->and($ozuColumn->getDefaultSortDirection())->toBe('desc'); }); -it('allows to use setDefaultSort with default value', function() { +it('allows to use setDefaultSort with default value', function () { $ozuColumn = OzuColumn::makeText('key', 1) ->setDefaultSort(); - expect($ozuColumn->getDefaultSortDirection())->toBe("asc"); + expect($ozuColumn->getDefaultSortDirection())->toBe('asc'); }); -it('sets default check values', function() { +it('sets default check values', function () { $ozuColumn = OzuColumn::makeCheck('key', 1); - expect($ozuColumn->type())->toBe("check") - ->and($ozuColumn->key())->toBe("key") + expect($ozuColumn->type())->toBe('check') + ->and($ozuColumn->key())->toBe('key') ->and($ozuColumn->size())->toBe(1) ->and($ozuColumn->label())->toBeNull(); }); -it('sets default date values', function() { +it('sets default date values', function () { $ozuColumn = OzuColumn::makeDate('key', 1); - expect($ozuColumn->type())->toBe("date") - ->and($ozuColumn->key())->toBe("key") + expect($ozuColumn->type())->toBe('date') + ->and($ozuColumn->key())->toBe('key') ->and($ozuColumn->size())->toBe(1) ->and($ozuColumn->label())->toBeNull(); }); -it('sets default image values', function() { +it('sets default image values', function () { $ozuColumn = OzuColumn::makeImage('key', 1); - expect($ozuColumn->type())->toBe("image") - ->and($ozuColumn->key())->toBe("key") + expect($ozuColumn->type())->toBe('image') + ->and($ozuColumn->key())->toBe('key') ->and($ozuColumn->size())->toBe(1) ->and($ozuColumn->label())->toBeNull(); }); - - diff --git a/tests/Unit/OzuFieldTest.php b/tests/Unit/OzuFieldTest.php index f26ded0..e11b2ca 100644 --- a/tests/Unit/OzuFieldTest.php +++ b/tests/Unit/OzuFieldTest.php @@ -73,7 +73,7 @@ 'helpMessage' => 'help', 'isUpdatable' => false, 'text' => 'text', - 'label' => null + 'label' => null, ]); }); @@ -187,7 +187,7 @@ 'hasLegend' => false, 'allowedExtensions' => ['jpg', 'jpeg', 'png', 'gif', 'webp'], 'maxFileSize' => 5, - 'cropRatio' => null + 'cropRatio' => null, ]); }); @@ -212,7 +212,7 @@ 'hasLegend' => true, 'allowedExtensions' => ['pdf'], 'maxFileSize' => 10, - 'cropRatio' => '16:9' + 'cropRatio' => '16:9', ]); }); @@ -233,7 +233,7 @@ 'hasLegend' => false, 'maxFileSize' => 5, 'cropRatio' => null, - 'maxItems' => 10 + 'maxItems' => 10, ]); }); @@ -258,7 +258,7 @@ 'hasLegend' => true, 'maxFileSize' => 10, 'cropRatio' => '16:9', - 'maxItems' => 5 + 'maxItems' => 5, ]); }); @@ -278,7 +278,7 @@ 'isUpdatable' => false, 'hasLegend' => false, 'maxFileSize' => 5, - 'maxItems' => 10 + 'maxItems' => 10, ]); }); @@ -301,7 +301,7 @@ 'isUpdatable' => false, 'hasLegend' => true, 'maxFileSize' => 10, - 'maxItems' => 4 + 'maxItems' => 4, ]); }); @@ -319,7 +319,7 @@ 'validationRules' => ['required'], 'helpMessage' => 'help', 'isUpdatable' => false, - 'hasTime' => false + 'hasTime' => false, ]); }); @@ -338,7 +338,6 @@ 'validationRules' => ['required'], 'helpMessage' => 'help', 'isUpdatable' => false, - 'hasTime' => true + 'hasTime' => true, ]); }); -