ResizeImage   A
last analyzed

Complexity

Total Complexity 36

Size/Duplication

Total Lines 209
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 79
c 1
b 0
f 0
dl 0
loc 209
rs 9.52
wmc 36

7 Methods

Rating   Name   Duplication   Size   Complexity  
B fire() 0 39 9
A __construct() 0 12 1
A removeImageSize() 0 7 5
B resizeImage() 0 57 11
A parseSizesString() 0 16 4
A moveThumbsToRemoteDisk() 0 16 4
A loadDisks() 0 6 2
1
<?php
2
3
namespace OkayBueno\Images\Commands;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Http\File;
7
use Illuminate\Support\Facades\Storage;
8
use OkayBueno\Images\Models\Image;
9
use OkayBueno\Images\Services\ImageServiceInterface;
10
use OkayBueno\Images\Services\src\ImageProcessingService;
11
12
/**
13
 * Class ResizeImage
14
 * @package OkayBueno\Images\Commands
15
 */
16
class ResizeImage extends Command
17
{
18
    protected $signature = 'images:resize {--image-id=} {--image-type=} {--sizes=}';
19
    protected $description = 'Resizes the image or group of images to the given sizes.';
20
21
    protected $imageService;
22
    protected $imageProcessingService;
23
    protected $cloudDisk;
24
    protected $localDisk;
25
    protected $localDiskBasePath;
26
27
    /**
28
     * @param ImageServiceInterface $imageServiceInterface
29
     * @param ImageProcessingService $imageProcessingService
30
     */
31
    public function __construct(
32
        ImageServiceInterface $imageServiceInterface,
33
        ImageProcessingService $imageProcessingService
34
    )
35
    {
36
        parent::__construct();
37
        $this->imageService = $imageServiceInterface;
38
        $this->imageProcessingService = $imageProcessingService;
39
40
        $this->loadDisks();
41
42
        $this->localDiskBasePath = trim( $this->localDisk->getAdapter()->getPathPrefix(), '/' );
43
    }
44
45
46
    /**
47
     *
48
     */
49
    public function fire()
50
    {
51
        $imageId = $this->option('image-id');
52
        $imageType = $this->option('image-type');
53
54
        if ( $imageId || $imageType )
55
        {
56
            $sizes = $this->option('sizes');
57
            $parsedSizes = $this->parseSizesString( $sizes );
58
59
            if ( $parsedSizes || empty( $parsedSizes ) )
60
            {
61
                // Find images or image type.
62
                if ( $imageId )
63
                {
64
                    $imageToResize = $this->imageService->findImageById( $imageId );
0 ignored issues
show
Bug introduced by
$imageId of type string is incompatible with the type integer expected by parameter $imageId of OkayBueno\Images\Service...erface::findImageById(). ( Ignorable by Annotation )

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

64
                    $imageToResize = $this->imageService->findImageById( /** @scrutinizer ignore-type */ $imageId );
Loading history...
65
66
                    if ( !is_array( $imageToResize ) )
67
                    {
68
                        // Destroy image.
69
                        $this->info("Resizing image #$imageToResize->id...");
70
                        $this->resizeImage( $imageToResize, $parsedSizes );
71
                        $this->info("Image #$imageToResize->id was resized.");
72
                    } else
73
                    {
74
                        $this->error("Image with $imageId does not exist.");
75
                    }
76
                } else if ( $imageType )
77
                {
78
                    foreach( Image::where('type', $imageType )->cursor() as $counter => $imageToResize  )
79
                    {
80
                        // Destroy image.
81
                        $this->info("Resizing image #$imageToResize->id...");
82
                        $this->resizeImage( $imageToResize, $parsedSizes );
83
                        $this->info("Image #$imageToResize->id was resized.");
84
                    }
85
                }
86
            } else $this->error('Please specify the sizes you want to resize the image to.');
87
        } else $this->error('Please specify either the image-type that you want to resize or the image-id.');
88
    }
89
90
91
    /**
92
     * @param Image $image
93
     * @param array $newSizes
94
     */
95
    protected function resizeImage( Image $image, array $newSizes )
96
    {
97
        foreach( $image->thumbnails( NULL, TRUE ) as $thumbKey => $thumb )
98
        {
99
            $folder = dirname( $thumb );
100
            $folderPath = explode('/', $folder );
101
102
            if ( is_array( $folderPath ) ) $existingSize = array_pop( $folderPath );
103
            else $existingSize = NULL;
104
105
            $existingSize = str_replace( '_', '', $existingSize );
106
107
            $existingSizeKey = array_search( $existingSize, $newSizes );
108
109
            if ( $existingSizeKey === FALSE )
110
            {
111
                // Remove the existing size.
112
                $this->removeImageSize( $thumb, TRUE );
113
            }
114
        }
115
116
        // If the image does not exist locally, copy it over.
117
        $folderName = dirname( $image->path );
0 ignored issues
show
Bug introduced by
The property path does not seem to exist on OkayBueno\Images\Models\Image. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
118
        if ( !$this->localDisk->exists( $image->path ) && $this->cloudDisk  )
119
        {
120
            if ( !$this->localDisk->exists( $folderName ) ) $this->localDisk->makeDirectory( $folderName, 0775);
121
122
            $fileContents = $this->cloudDisk->get( $image->path );
123
            $this->localDisk->put( $image->path, $fileContents );
124
        }
125
126
        $finalThumbs = [];
127
128
        foreach( $newSizes as $sizeKey => $size )
129
        {
130
            // At this point, old images are removed, so we can convert to new sizes.
131
            $newThumbs = $this->imageProcessingService->resizeOrCropImageToSizes( $image->path, $folderName, [ $size ] );
132
133
            if ( $newThumbs && !empty( $newThumbs ) )
134
            {
135
                $thumb =  array_first( $newThumbs );
136
                $finalThumbs[ $sizeKey ] = $thumb;
137
            }
138
139
            // Move thumbs to the cloud disk.
140
            if ( $this->cloudDisk )
141
            {
142
                $this->moveThumbsToRemoteDisk( $newThumbs, $image->filename );
0 ignored issues
show
Bug introduced by
The property filename does not seem to exist on OkayBueno\Images\Models\Image. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
143
            }
144
        }
145
146
        // Update the file.
147
        $update = [
148
            'thumbnails' => json_encode( $finalThumbs ),
149
        ];
150
151
        $image->update( $update );
152
153
    }
154
155
156
    /**
157
     * @param $sizes
158
     * @return array
159
     */
160
    protected function parseSizesString( $sizes )
161
    {
162
        $parsedSizes = [];
163
164
        $explodedSizes = explode( ',', $sizes );
165
166
        foreach( $explodedSizes as $sizeString )
167
        {
168
            $explodedSizeString = explode( ':', $sizeString );
169
            if ( is_array( $explodedSizeString ) && count( $explodedSizeString ) >= 2 )
170
            {
171
                $parsedSizes[ $explodedSizeString[0] ] = $explodedSizeString[1];
172
            }
173
        }
174
175
        return $parsedSizes;
176
    }
177
178
    /**
179
     * @param $pathFromDisk
180
     * @param bool|false $alsoFromCloud
181
     */
182
    protected function removeImageSize( $pathFromDisk, $alsoFromCloud = FALSE  )
183
    {
184
        if ( $this->localDisk->exists( $pathFromDisk ) ) $this->localDisk->delete( $pathFromDisk );
185
186
        if ( $alsoFromCloud && $this->cloudDisk )
187
        {
188
            if ( $this->cloudDisk->exists( $pathFromDisk ) ) $this->cloudDisk->delete( $pathFromDisk );
189
        }
190
    }
191
192
193
    /**
194
     *
195
     */
196
    protected function loadDisks()
197
    {
198
        $this->localDisk = Storage::disk( config( 'images.local_disk_name', 'local' ) );
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

198
        $this->localDisk = Storage::disk( /** @scrutinizer ignore-call */ config( 'images.local_disk_name', 'local' ) );
Loading history...
199
200
        $cloudDiskName = config( 'images.cloud_disk_name', NULL );
201
        if ( $cloudDiskName ) $this->cloudDisk = Storage::disk( $cloudDiskName );
202
    }
203
204
205
    /**
206
     * @param $thumbs
207
     * @param $filename
208
     */
209
    protected function moveThumbsToRemoteDisk( $thumbs, $filename )
210
    {
211
        foreach( $thumbs as $thumb )
212
        {
213
            if ( !$this->cloudDisk->exists( $thumb ) )
214
            {
215
                $folderName = dirname( $thumb );
216
                // And move them to the cloud.
217
                $thumbFile = new File( get_path_to( $this->localDiskBasePath, $thumb ) );
218
                $this->cloudDisk->putFileAs( $folderName, $thumbFile, $filename );
219
220
                // Remove from local.
221
                if ( $this->localDisk->exists( $thumb ) ) $this->localDisk->delete( $thumb );
222
            }
223
224
            $this->removeImageSize( $thumb, FALSE );
225
        }
226
    }
227
228
229
230
231
}