composed project, added packages, models, controllers, seeders, mirgations etc.

This commit is contained in:
2024-07-28 17:45:09 +03:00
parent 5d05ee373a
commit 56eec65355
73 changed files with 3576 additions and 368 deletions

View File

@@ -0,0 +1,17 @@
<?php
/**
* @package: events-venues-task
* @author: Yevhen Odynets
* @date: 2024-07-26
* @time: 19:44
*/
declare(strict_types=1);
namespace App\Services\Faker\Image\Contracts;
enum FakerImageProviderType
{
case LoremFlickr;
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* @package: events-venues-task
* @author: Yevhen Odynets
* @date: 2024-07-26
* @time: 19:51
*/
declare(strict_types=1);
namespace App\Services\Faker\Image\Contracts;
interface ProviderFactoryInterface
{
public static function apply(): ProviderInterface;
}

View File

@@ -0,0 +1,57 @@
<?php
/**
* @package: events-venues-task
* @author: Yevhen Odynets
* @date: 2024-07-26
* @time: 19:48
*/
declare(strict_types=1);
namespace App\Services\Faker\Image\Contracts;
use App\Services\Faker\Image\ImageStorage;
interface ProviderInterface
{
public const array KEYWORDS
= [
'tournament',
'match',
'game',
'fight',
'championship',
'date',
'contest',
'competition',
'event',
'advent',
'meeting',
'adventure',
'convention',
'gathering',
'council',
'committee',
'seminar',
'congregation',
'symposium',
'congress',
'assembly',
'forum',
'colloquium',
'convocation',
'marvel',
'conference',
'celebration',
'holiday',
'ceremony',
];
/**
* @param ImageStorage $storage
*
* @return string|null
*/
public function getImage(ImageStorage $storage): ?string;
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* @package: events-venues-task
* @author: Yevhen Odynets
* @date: 2024-07-26
* @time: 19:56
*/
declare(strict_types=1);
namespace App\Services\Faker\Image;
use App\Services\Faker\Image\Providers\LoremFlickrFactory;
use App\Services\Faker\Image\Contracts\{ProviderFactoryInterface, FakerImageProviderType};
use RuntimeException;
class FakerImageProvider
{
public static function use(FakerImageProviderType $type): ProviderFactoryInterface
{
if ($type === FakerImageProviderType::LoremFlickr) {
{
return new LoremFlickrFactory();
}
} else {
{
throw new RuntimeException("Unknown image provider: " . $type->name);
}
}
}
}

View File

@@ -0,0 +1,70 @@
<?php
/**
* @package: events-venues-task
* @author: Yevhen Odynets
* @date: 2024-07-26
* @time: 19:20
*/
//phpcs:ignore
declare(strict_types = 1);
namespace App\Services\Faker\Image;
use Illuminate\Support\Arr;
class ImageStorage
{
private string $destFolder;
private int $width;
private int $height;
private array $keywords;
public function __construct(string $destFolder, int $width, int $height, array $keywords = [])
{
$this->destFolder = $destFolder;
$this->width = $width;
$this->height = $height;
$this->keywords = $keywords;
}
/**
* @return string
*/
public function getFolder(): string
{
return $this->destFolder;
}
/**
* @return int
*/
public function getWidth(): int
{
return $this->width;
}
/**
* @return int
*/
public function getHeight(): int
{
return $this->height;
}
/**
* @param string $prefix
* @param string $suffix
*
* @return string|null
*/
public function getKeyword(string $prefix = '', string $suffix = ''): ?string
{
if (count($this->keywords) === 0) {
return null;
}
return $prefix . Arr::random($this->keywords) . $suffix;
}
}

View File

@@ -0,0 +1,69 @@
<?php
/**
* @package: events-venues-task
* @author: Yevhen Odynets
* @date: 2024-07-26
* @time: 22:54
*/
//phpcs:ignore
declare(strict_types=1);
namespace App\Services\Faker\Image;
use App\Facades\Image;
use App\Services\Faker\Image\{Contracts\ProviderInterface};
use Error;
use Illuminate\Support\{Facades\Http, Facades\Storage, Str};
abstract class Provider implements ProviderInterface
{
public ?string $url = null;
abstract public function getImage(ImageStorage $storage): ?string;
/**
* @param ImageStorage $storage
* @param string|null $url
*
* @return string|null
*/
protected function download(ImageStorage $storage, ?string $url): ?string
{
$storagePath = Str::of($storage->getFolder()) . '/' . Str::uuid()->toString() . '.jpg';
$response = Http::get($url);
if ($response->successful() === false) {
appNotice("Couldn't download image from $url");
return null;
}
$result = Storage::disk("local")->put($storagePath, $response->body());
$verify = $this->verify($storagePath, config('image.faker.cropper'));
return $result && $verify !== "NULL" ? $verify : "NULL";
}
private function verify(string $storagePath, ?array $cropper = []): string
{
$fullPath = Image::localPath($storagePath);
if (is_null($fullPath)) {
appNotice("Couldn't locate image from $storagePath");
return "NULL";
}
$meta = Image::meta($fullPath);
if (empty($meta)) {
appNotice("Couldn't retrieve image meta from $fullPath");
return "NULL";
}
try {
return Image::cropAlign($fullPath, $storagePath, ...$cropper);
} catch (Error $err) {
//Image::log($err, LoggingSeverityLevelsType::emergency);
return "NULL";
}
}
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* @package: events-venues-task
* @author: Yevhen Odynets
* @date: 2024-07-26
* @time: 19:48
*/
declare(strict_types=1);
namespace App\Services\Faker\Image\Providers;
use App\Services\Faker\Image\{ImageStorage, Provider};
final class LoremFlickr extends Provider
{
public function getImage(ImageStorage $storage): ?string
{
$this->url = config('image.faker.provider.loremflickr.host') .
$storage->getWidth() . "/" . $storage->getHeight() . $storage->getKeyword('/');
return $this->download($storage, $this->url);
}
}

View File

@@ -0,0 +1,22 @@
<?php
/**
* @package: events-venues-task
* @author: Yevhen Odynets
* @date: 2024-07-26
* @time: 20:03
*/
declare(strict_types=1);
namespace App\Services\Faker\Image\Providers;
use App\Services\Faker\Image\Contracts\{ProviderFactoryInterface, ProviderInterface};
class LoremFlickrFactory implements ProviderFactoryInterface
{
public static function apply(): ProviderInterface
{
return new LoremFlickr();
}
}