Completed
Push — master ( d244a1...8fd770 )
by Anton
01:17
created

PostAction::getInstalledRequirements()   A

Complexity

Conditions 5
Paths 16

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 32
rs 9.0968
c 0
b 0
f 0
cc 5
nc 16
nop 0
1
<?php
2
3
/*
4
 * This file is part of Laravel Paket.
5
 *
6
 * (c) Anton Komarev <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Cog\Laravel\Paket\Http\Controllers\Api\Jobs;
15
16
use Cog\Contracts\Paket\Job\Repositories\Job as JobRepositoryContract;
17
use Cog\Contracts\Paket\Requirement\Entities\Requirement as RequirementContract;
18
use Cog\Laravel\Paket\Job\Entities\Job;
19
use Cog\Laravel\Paket\Job\Events\JobHasBeenCreated;
20
use Cog\Laravel\Paket\Process\Entities\Process;
21
use Cog\Laravel\Paket\Requirement\Entities\Requirement;
22
use Illuminate\Contracts\Support\Responsable as ResponsableContract;
23
use Illuminate\Support\Arr;
24
use Illuminate\Support\Carbon;
25
use Illuminate\Validation\ValidationException;
26
use MCStreetguy\ComposerParser\Factory as ComposerParser;
27
use Ramsey\Uuid\Uuid;
28
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
29
30
final class PostAction
31
{
32
    private $jobs;
33
34
    public function __construct(JobRepositoryContract $jobs)
35
    {
36
        $this->jobs = $jobs;
37
    }
38
39
    public function __invoke(PostRequest $request): ResponsableContract
40
    {
41
        $type = $request->input('type');
42
        $requirement = Requirement::fromArray($request->input('requirement'));
43
44
        if ($type === 'RequirementInstall') {
45
            if ($this->isRequirementInstalled($requirement)) {
46
                throw ValidationException::withMessages([
47
                    'name' => [
48
                        "Package `{$requirement}` already installed",
49
                    ],
50
                ]);
51
            }
52
        } else {
53
            $requirement = $this->getInstalledRequirement($requirement);
54
        }
55
56
        $job = new Job(
57
            $type,
58
            strval(Uuid::uuid4()),
59
            'Pending',
60
            Carbon::now(),
61
            new Process(),
62
            $requirement
63
        );
64
65
        $this->jobs->store($job);
66
67
        event(new JobHasBeenCreated($job));
68
69
        return new PostResponse($job);
70
    }
71
72
    private function getInstalledRequirements(): array
73
    {
74
        $lockFile = ComposerParser::parseLockfile(base_path('composer.lock'));
75
76
        $packages = $lockFile->getPackages()->getData();
77
        $devPackages = $lockFile->getPackagesDev()->getData();
78
        $platform = $lockFile->getPlatform()->getData();
79
        $devPlatform = $lockFile->getPlatformDev()->getData();
80
        foreach ($packages as &$package) {
81
            $package['isDevelopment'] = false;
82
        }
83
        foreach ($devPackages as &$package) {
84
            $package['isDevelopment'] = true;
85
        }
86
        $platforms = [];
87
        foreach ($platform as $name => $version) {
88
            $platforms[] = [
89
                'name' => $name,
90
                'version' => $version,
91
                'isDevelopment' => false,
92
            ];
93
        }
94
        foreach ($devPlatform as $name => $version) {
95
            $platforms[] = [
96
                'name' => $name,
97
                'version' => $version,
98
                'isDevelopment' => true,
99
            ];
100
        }
101
102
        return array_merge($packages, $devPackages, $platforms);
103
    }
104
105
    private function getInstalledRequirement(RequirementContract $requirement): RequirementContract
106
    {
107
        $installedRequirements = $this->getInstalledRequirements();
108
109
        $installedRequirement = Arr::first($installedRequirements, function (array $value) use ($requirement) {
110
            return $value['name'] === $requirement->getName();
111
        });
112
113
        if (is_null($installedRequirement)) {
114
            throw new NotFoundHttpException();
115
        }
116
117
        $requirement = Requirement::fromArray($installedRequirement);
118
119
        return $requirement;
120
    }
121
122
    private function isRequirementInstalled(RequirementContract $requirement): bool
123
    {
124
        $installedRequirements = $this->getInstalledRequirements();
125
126
        $installedRequirement = Arr::first($installedRequirements, function (array $value) use ($requirement) {
127
            return $value['name'] === $requirement->getName();
128
        });
129
130
        return !is_null($installedRequirement)
131
            && $installedRequirement['version'] === $requirement->getVersion()
132
            && $installedRequirement['isDevelopment'] === $requirement->isDevelopment();
133
    }
134
}
135