SyncCommand   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 1
Metric Value
wmc 10
eloc 52
c 4
b 0
f 1
dl 0
loc 125
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A handle() 0 33 5
A filesToSync() 0 32 4
A filesToDelete() 0 9 1
1
<?php
2
3
namespace Arubacao\AssetCdn\Commands;
4
5
use Arubacao\AssetCdn\Finder;
6
use Illuminate\Config\Repository;
7
use Illuminate\Filesystem\FilesystemManager;
8
use Illuminate\Http\File;
9
use Symfony\Component\Finder\SplFileInfo;
10
11
class SyncCommand extends BaseCommand
12
{
13
    /**
14
     * The name and signature of the console command.
15
     *
16
     * @var string
17
     */
18
    protected $signature = 'asset-cdn:sync';
19
20
    /**
21
     * The console command description.
22
     *
23
     * @var string
24
     */
25
    protected $description = 'Synchronizes assets to CDN';
26
27
    /**
28
     * @var string
29
     */
30
    private $filesystem;
31
32
    /**
33
     * @var FilesystemManager
34
     */
35
    private $filesystemManager;
36
37
    /**
38
     * Execute the console command.
39
     *
40
     * @param Finder $finder
41
     * @param FilesystemManager $filesystemManager
42
     * @param Repository $config
43
     *
44
     * @return void
45
     */
46
    public function handle(Finder $finder, FilesystemManager $filesystemManager, Repository $config)
47
    {
48
        $this->filesystem = $config->get('asset-cdn.filesystem.disk');
49
        $this->filesystemManager = $filesystemManager;
50
        $filesOnCdn = $this->filesystemManager
51
            ->disk($this->filesystem)
52
            ->allFiles();
53
        $localFiles = $finder->getFiles();
54
        $filesToDelete = $this->filesToDelete($filesOnCdn, $localFiles);
55
        $filesToSync = $this->filesToSync($filesOnCdn, $localFiles);
56
57
        foreach ($filesToSync as $file) {
58
            $bool = $this->filesystemManager
59
                ->disk($this->filesystem)
60
                ->putFileAs(
61
                    $file->getRelativePath(),
62
                    new File($file->getPathname()),
63
                    $file->getFilename(),
64
                    $config->get('asset-cdn.filesystem.options')
65
                );
66
67
            if (! $bool) {
68
                $this->error("Problem uploading: {$file->getRelativePathname()}");
69
            } else {
70
                $this->info("Successfully uploaded: {$file->getRelativePathname()}");
71
            }
72
        }
73
74
        if ($this->filesystemManager
75
            ->disk($this->filesystem)
76
            ->delete($filesToDelete)) {
77
            foreach ($filesToDelete as $file) {
78
                $this->info("Successfully deleted: {$file}");
79
            }
80
        }
81
    }
82
83
    /**
84
     * @param string[] $filesOnCdn
85
     * @param SplFileInfo[] $localFiles
86
     * @return SplFileInfo[]
87
     */
88
    private function filesToSync(array $filesOnCdn, array $localFiles): array
89
    {
90
        $array = array_filter($localFiles, function (SplFileInfo $localFile) use ($filesOnCdn) {
91
            $localFilePathname = $localFile->getRelativePathname();
92
            if (! in_array($localFilePathname, $filesOnCdn)) {
93
                return true;
94
            }
95
96
            $filesizeOfCdn = $this->filesystemManager
97
                ->disk($this->filesystem)
98
                ->size($localFilePathname);
99
100
            if ($filesizeOfCdn != $localFile->getSize()) {
101
                return true;
102
            }
103
104
            $md5OfCdn = md5(
105
                $this->filesystemManager
106
                    ->disk($this->filesystem)
107
                    ->get($localFilePathname)
108
            );
109
110
            $md5OfLocal = md5_file($localFile->getRealPath());
111
112
            if ($md5OfLocal != $md5OfCdn) {
113
                return true;
114
            }
115
116
            return false;
117
        });
118
119
        return array_values($array);
120
    }
121
122
    /**
123
     * @param string[] $filesOnCdn
124
     * @param SplFileInfo[] $localFiles
125
     * @return string[]
126
     */
127
    private function filesToDelete(array $filesOnCdn, array $localFiles): array
128
    {
129
        $localFiles = $this->mapToPathname($localFiles);
130
131
        $array = array_filter($filesOnCdn, function (string $fileOnCdn) use ($localFiles) {
132
            return ! in_array($fileOnCdn, $localFiles);
133
        });
134
135
        return array_values($array);
136
    }
137
}
138