Passed
Push — master ( 240c83...03f39b )
by Mathias
06:41
created

ImageSetHydrator::hydrate()   B

Complexity

Conditions 8
Paths 12

Size

Total Lines 37
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 8

Importance

Changes 0
Metric Value
eloc 20
dl 0
loc 37
ccs 16
cts 16
cp 1
rs 8.4444
c 0
b 0
f 0
cc 8
nc 12
nop 2
crap 8
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @license MIT
7
 * @copyright https://yawik.org/COPYRIGHT.php
8
 */
9
10
/** */
11
namespace Core\Entity\Hydrator;
12
13
use Core\Entity\ImageSet;
14
use Core\Entity\ImageSetInterface;
15
use Core\Service\FileManager;
16
use Core\Options\ImageSetOptions;
17
use Imagine\Image\Box;
18
use Imagine\Image\ImageInterface as ImagineImage;
19
use Core\Entity\ImageInterface;
20
use Imagine\Image\ImagineInterface;
21
use Laminas\Hydrator\HydratorInterface;
22
23
/**
24
 * Hydrator for ImageSets.
25
 *
26
 * @see \Core\Entity\ImageSetInterface
27
 * @author Mathias Gelhausen <[email protected]>
28
 * @since 0.29
29
 */
30
class ImageSetHydrator implements HydratorInterface
31
{
32
    protected ImagineInterface $imagine;
33
    protected ImageSetOptions $options;
34
    protected FileManager $fileManager;
35
36
    public function __construct(FileManager $fileManager, ImagineInterface $imagine, ImageSetOptions $options)
37
    {
38
        $this->imagine = $imagine;
39
        $this->options = $options;
40
        $this->fileManager = $fileManager;
41
    }
42
43
    /**
44
     * Extract values from an object
45
     *
46 5
     * @param object $object
47
     *
48 5
     * @return array
49 5
     */
50
    public function extract($object): array
51
    {
52
        if (!$object instanceof ImageSetInterface || !($image = $object->get(ImageSetInterface::ORIGINAL))) {
53
            return [];
54
        }
55
56
        return [$this->options->getFormElementName() => $image->getId()];
57
    }
58
59 2
    /**
60
     * Hydrate $object with the provided $data.
61 2
     *
62 1
     * @param  array  $data
63
     * @param  object|ImageSetInterface $object
64
     *
65 1
     * @return object
66
     */
67
    public function hydrate(array $data, $object)
68
    {
69
        if (!isset($data['original']) || UPLOAD_ERR_OK !== $data['original']['error']) {
70
            return $object;
71
        }
72
73
        $data = $data['original'];
74
        $file  = $data['tmp_name'];
75
76 2
        if(!is_readable($file)){
77
            throw new \Exception("File '$file' is unreadable.");
78 2
        }
79 1
80
        $image = $this->imagine->open($file);
81
        $imageSpecs = $this->options->getImages();
82 1
        $images = [];
83 1
84
        // add original image
85 1
        $images['original'] = $this->createGridFSFile($object->getId(), $file, $data);
0 ignored issues
show
Bug introduced by
It seems like $object->getId() can also be of type null; however, parameter $imageSetId of Core\Entity\Hydrator\Ima...tor::createGridFSFile() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

85
        $images['original'] = $this->createGridFSFile(/** @scrutinizer ignore-type */ $object->getId(), $file, $data);
Loading history...
Bug introduced by
Are you sure the assignment to $images['original'] is correct as $this->createGridFSFile(...>getId(), $file, $data) targeting Core\Entity\Hydrator\Ima...tor::createGridFSFile() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
86 1
87
        foreach ($imageSpecs as $key => $size) {
88
            $newImage = ImageSetInterface::THUMBNAIL == $key
89 1
                ? $image->thumbnail(new Box($size[0], $size[1]), ImagineImage::THUMBNAIL_INSET)
90
                : $this->createImage($image, $size);
91 1
92 1
            if ($newImage) {
93 1
                $entity = $this->createGridFSFile($object->getId(), $newImage, $data, $key);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $entity is correct as $this->createGridFSFile(...$newImage, $data, $key) targeting Core\Entity\Hydrator\Ima...tor::createGridFSFile() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
94 1
                $images[$key] = $entity;
95
            }
96 1
        }
97 1
98 1
        /* @var ImageInterface $image */
99
        foreach($images as $key => $image) {
100
            $object->add($image);
101
        }
102 1
103
        return $object;
104 1
    }
105
106
    private function createImage(ImagineImage $image, $size)
107 1
    {
108
        $imageSize = $image->getSize();
109 1
110
        if ($imageSize->getWidth() <= $size[0] && $imageSize->getHeight() <= $size[1]) {
111 1
            return null;
112 1
        }
113
114
        if ($imageSize->getWidth() > $size[0]) {
115 1
            $imageSize = $imageSize->widen($size[0]);
116 1
        }
117
118
        if ($imageSize->getHeight() > $size[1]) {
119 1
            $imageSize = $imageSize->heighten($size[1]);
120 1
        }
121
122
        $image = $image->resize($imageSize);
123 1
124
        return $image;
125 1
    }
126
127
    /**
128 1
     * @param string $imageSetId
129
     * @param string|ImagineImage $image
130
     * @param array $data
131 1
     * @param string $prefix
132
     *
133
     * @return void
134 1
     */
135 1
    private function createGridFSFile(string $imageSetId, $image, array &$data, string $prefix = "")
136
    {
137 1
        /* @var \Core\Entity\ImageInterface $entity */
138
        /* @var \Core\Entity\ImageMetadata $metadata */
139 1
        $metadata = $this->options->getMetadata();
140 1
        $fileManager = $this->fileManager;
141
        $name = ($prefix ? "$prefix-" : '') . $data['name'];
142
        $key = "" == $prefix ? "original":$prefix;
143
        $metadata->setContentType($data['type']);
144 1
        $metadata->setBelongsTo($imageSetId);
145 1
        $metadata->setKey($key);
146 1
        $entityClass = $this->options->getEntityClass();
147
148
        if (is_string($image)) {
149 1
            $file = $image;
150
        }else{
151
            $format = str_replace('image/', '', $data['type']);
152
            $content = $image->get($format);
153
            $file = '/tmp/php'.md5($content);
154
            file_put_contents($file, $content);
155
        }
156
157
        return $fileManager->uploadFromFile($entityClass, $metadata, $file, $name);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $fileManager->upl...metadata, $file, $name) returns the type object which is incompatible with the documented return type void.
Loading history...
158
    }
159
}
160