Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
84.38% covered (warning)
84.38%
27 / 32
44.44% covered (danger)
44.44%
4 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
FileUri
84.38% covered (warning)
84.38%
27 / 32
44.44% covered (danger)
44.44%
4 / 9
13.64
0.00% covered (danger)
0.00%
0 / 1
 toFile
90.00% covered (success)
90.00%
9 / 10
0.00% covered (danger)
0.00%
0 / 1
4.02
 getStream
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 moveTo
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSize
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getError
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getClientFilename
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getClientMediaType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 createRandom
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 createSchema
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2namespace Apie\Core\ValueObjects;
3
4use Apie\Core\Attributes\Description;
5use Apie\Core\Attributes\FakeMethod;
6use Apie\Core\Attributes\SchemaMethod;
7use Apie\Core\FileStorage\StoredFile;
8use Faker\Generator;
9use Psr\Http\Message\StreamInterface;
10use Psr\Http\Message\UploadedFileInterface;
11use ReflectionClass;
12use ReflectionProperty;
13
14/**
15 * @phpstan-ignore apie.conflicting.interface
16 */
17#[Description('URL to download file')]
18#[FakeMethod('createRandom')]
19#[SchemaMethod('createSchema')]
20class FileUri extends Uri implements UploadedFileInterface
21{
22    private StoredFile $loadedFile;
23
24    final protected function toFile(): UploadedFileInterface
25    {
26        if (!isset($this->loadedFile)) {
27            $contentType = null;
28            if (class_exists('GuzzleHttp\Client')) {
29                $client = new \GuzzleHttp\Client();
30                try {
31                    $response = $client->request('HEAD', $this->toNative());
32                    $contentType = $response->getHeaderLine('Content-Type');
33                    // Use $contentType as needed
34                } catch (\Exception $e) {
35                    // Fallback to existing logic
36                }
37            }
38            $stream = fopen($this->toNative(), 'rb');
39            $this->loadedFile = StoredFile::createFromResource($stream, clientMimeType: $contentType);
40        }
41        
42        return $this->loadedFile;
43    }
44
45    public function getStream(): StreamInterface
46    {
47        return $this->toFile()->getStream();
48    }
49
50    public function moveTo($targetPath): void
51    {
52        $this->toFile()->moveTo($targetPath);
53    }
54
55    public function getSize(): ?int
56    {
57        return $this->toFile()->getSize();
58    }
59
60    public function getError(): int
61    {
62        return $this->toFile()->getError();
63    }
64
65    public function getClientFilename(): ?string
66    {
67        return $this->toFile()->getClientFilename();
68    }
69
70    public function getClientMediaType(): ?string
71    {
72        return $this->toFile()->getClientMediaType();
73    }
74
75    public static function createRandom(Generator $faker): Uri
76    {
77        $refl = new ReflectionClass(static::class);
78        $instance = $refl->newInstanceWithoutConstructor();
79        $prop = new ReflectionProperty(Uri::class, 'internal');
80        $prop->setValue($instance, $faker->url());
81        $instance->loadedFile = $faker->fakeClass(StoredFile::class);
82        return $instance;
83    }
84
85    /**
86     * @return array<string, string|null>
87     */
88    public static function createSchema(): array
89    {
90        $attr = new ReflectionClass(static::class);
91        $description = null;
92        foreach ($attr->getAttributes(Description::class) as $descriptionAttr) {
93            $descriptionInstance = $descriptionAttr->newInstance();
94            $description = $descriptionInstance->description;
95        }
96        return [
97            'type' => 'string',
98            'format' => 'fileuri',
99            'description' => $description,
100        ];
101    }
102}