• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wimski / laravel-model-repositories / 13542544090

26 Feb 2025 11:11AM UTC coverage: 98.765% (-1.2%) from 100.0%
13542544090

push

github

wimski
normalize composer.json

160 of 162 relevant lines covered (98.77%)

13.14 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.48
/src/Console/Commands/ModelRepositoryMakeCommand.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Wimski\ModelRepositories\Console\Commands;
6

7
use Exception;
8
use Illuminate\Console\GeneratorCommand;
9
use Illuminate\Filesystem\Filesystem;
10
use Symfony\Component\Console\Input\InputArgument;
11
use Symfony\Component\Console\Input\InputOption;
12
use Wimski\ModelRepositories\Contracts\Resolvers\NamespaceResolverInterface;
13
use Wimski\ModelRepositories\Contracts\Resolvers\StubsPathResolverInterface;
14
use Wimski\ModelRepositories\DataObjects\NamespaceDataObject;
15

16
class ModelRepositoryMakeCommand extends GeneratorCommand
17
{
18
    protected NamespaceDataObject $namespace;
19
    protected string $model;
20
    protected $name = 'make:repository';
21
    protected $description = 'Create a new model repository class';
22

23
    public function __construct(
24
        Filesystem $files,
25
        protected readonly NamespaceResolverInterface $namespaceResolver,
26
        protected readonly StubsPathResolverInterface $stubsPathResolver
27
    ) {
28
        parent::__construct($files);
48✔
29
    }
30

31
    public function handle(): ?bool
32
    {
33
        $this->model = $this->qualifyClass($this->getModelInput());
5✔
34

35
        if (! $this->getContractInput() || ! $this->getRepositoryInput()) {
5✔
36
            try {
37
                $this->namespace = $this->namespaceResolver->resolve($this->model);
4✔
38
            } catch (Exception $exception) {
1✔
39
                $this->error($exception->getMessage());
1✔
40
                return false;
1✔
41
            }
42
        }
43

44
        $contract   = $this->getContract();
4✔
45
        $repository = $this->getRepository();
4✔
46

47
        if ($this->alreadyExists($contract) || $this->alreadyExists($repository)) {
4✔
48
            $this->error('Repository already exists!');
1✔
49
            return false;
1✔
50
        }
51

52
        $contractPath   = $this->getPath($contract);
3✔
53
        $repositoryPath = $this->getPath($repository);
3✔
54

55
        $this->makeDirectory($contractPath);
3✔
56
        $this->makeDirectory($repositoryPath);
3✔
57

58
        $this->files->put($contractPath, $this->sortImports($this->buildContractClass($contract)));
3✔
59
        $this->files->put($repositoryPath, $this->sortImports($this->buildRepositoryClass($contract, $repository)));
3✔
60

61
        $this->info('Repository created successfully.');
3✔
62

63
        return null;
3✔
64
    }
65

66
    protected function getModelInput(): string
67
    {
68
        /** @var string $argument */
69
        $argument = $this->argument('model');
5✔
70

71
        return trim($argument);
5✔
72
    }
73

74
    protected function getContractInput(): ?string
75
    {
76
        /** @var ?string $option */
77
        $option = $this->option('contract');
5✔
78

79
        return $option ? trim($option) : $option;
5✔
80
    }
81

82
    protected function getRepositoryInput(): ?string
83
    {
84
        /** @var ?string $option */
85
        $option = $this->option('repository');
4✔
86

87
        return $option ? trim($option) : $option;
4✔
88
    }
89

90
    protected function getContract(): string
91
    {
92
        if ($this->getContractInput()) {
4✔
93
            return $this->getContractInput();
1✔
94
        }
95

96
        $model = str_replace($this->namespace->getModelsNamespace(), '', $this->model);
3✔
97

98
        return ltrim($this->namespace->getContractsNamespace() . $model . 'RepositoryInterface', '\\');
3✔
99
    }
100

101
    protected function getRepository(): string
102
    {
103
        if ($this->getRepositoryInput()) {
4✔
104
            return $this->getRepositoryInput();
1✔
105
        }
106

107
        $model = str_replace($this->namespace->getModelsNamespace(), '', $this->model);
3✔
108

109
        return ltrim($this->namespace->getRepositoriesNamespace() . $model . 'Repository', '\\');
3✔
110
    }
111

112
    protected function buildContractClass(string $contract): string
113
    {
114
        $stub = $this->files->get(
3✔
115
            $this->resolveStubPath('model.repository.interface.stub'),
3✔
116
        );
3✔
117

118
        return $this->replaceNamespace($stub, $contract)
3✔
119
            ->replaceModel($stub)
3✔
120
            ->replaceClass($stub, $contract);
3✔
121
    }
122

123
    protected function buildRepositoryClass(string $contract, string $repository): string
124
    {
125
        $stub = $this->files->get(
3✔
126
            $this->resolveStubPath('model.repository.stub'),
3✔
127
        );
3✔
128

129
        return $this->replaceNamespace($stub, $repository)
3✔
130
            ->replaceModel($stub)
3✔
131
            ->replaceContract($stub, $contract)
3✔
132
            ->replaceClass($stub, $repository);
3✔
133
    }
134

135
    protected function replaceModel(string &$stub): self
136
    {
137
        $class = str_replace($this->getNamespace($this->model) . '\\', '', $this->model);
3✔
138

139
        $stub = str_replace('{{ namespacedModel }}', $this->model, $stub);
3✔
140
        $stub = str_replace('{{ model }}', $class, $stub);
3✔
141

142
        return $this;
3✔
143
    }
144

145
    protected function replaceContract(string &$stub, string $contract): self
146
    {
147
        $class = str_replace($this->getNamespace($contract) . '\\', '', $contract);
3✔
148

149
        $stub = str_replace('{{ namespacedRepositoryInterface }}', $contract, $stub);
3✔
150
        $stub = str_replace('{{ repositoryInterface }}', $class, $stub);
3✔
151

152
        return $this;
3✔
153
    }
154

155
    protected function resolveStubPath(string $stub): string
156
    {
157
        return $this->files->exists($customPath = $this->stubsPathResolver->resolveAppPath($stub))
3✔
158
            ? $customPath
1✔
159
            : $this->stubsPathResolver->resolvePackagePath($stub);
3✔
160
    }
161

162
    protected function getStub(): string
163
    {
164
        // This abstract method must be implemented, but is not used.
165
        return '';
×
166
    }
167

168
    /**
169
     * @return array<array-key, array{0: string, 1: int, 2: string}>
170
     */
171
    protected function getArguments(): array
172
    {
173
        return [
48✔
174
            ['model', InputArgument::REQUIRED, 'The FQN of the model to make a repository for'],
48✔
175
        ];
48✔
176
    }
177

178
    /**
179
     * @return array<array-key, array{0: string, 1: null, 2: int, 3: string}>
180
     */
181
    protected function getOptions(): array
182
    {
183
        return [
48✔
184
            ['contract', null, InputOption::VALUE_OPTIONAL, 'The FQN of the repository interface to generate'],
48✔
185
            ['repository', null, InputOption::VALUE_OPTIONAL, 'The FQN of the repository class to generate'],
48✔
186
        ];
48✔
187
    }
188
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc