Skip to content

Commit 6199844

Browse files
committed
Leverage controller context + query statements
1 parent 89bbc4c commit 6199844

File tree

13 files changed

+347
-65
lines changed

13 files changed

+347
-65
lines changed

src/Generators/ControllerGenerator.php

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ private function buildMethods(Controller $controller)
7474
$reference = 'App\\' . $context;
7575
$variable = '$' . Str::camel($context);
7676

77-
// TODO: verify is model
77+
// TODO: verify controller prefix references a model
7878
$search = ' * @return \\Illuminate\\Http\\Response';
79-
$method = str_replace($search,' * @param \\' . $reference . ' ' . $variable . PHP_EOL . $search, $method);
79+
$method = str_replace($search, ' * @param \\' . $reference . ' ' . $variable . PHP_EOL . $search, $method);
8080

8181
$search = '(Request $request';
82-
$method = str_replace($search, $search . ', ' . $context . ' ' . $variable, $method);
82+
$method = str_replace($search, $search . ', ' . $context . ' ' . $variable, $method);
8383
$this->addImport($controller, $reference);
8484
}
8585

@@ -111,11 +111,11 @@ private function buildMethods(Controller $controller)
111111
} elseif ($statement instanceof SessionStatement) {
112112
$body .= self::INDENT . $statement->output() . PHP_EOL;
113113
} elseif ($statement instanceof EloquentStatement) {
114-
// TODO: pass controller method for context..
115-
$body .= self::INDENT . $statement->output($name) . PHP_EOL;
116-
$this->addImport($controller, 'App\\' . Str::studly($statement->reference()));
114+
$body .= self::INDENT . $statement->output($controller->prefix(), $name) . PHP_EOL;
115+
$this->addImport($controller, 'App\\' . $this->determineModel($controller->prefix(), $statement->reference()));
117116
} elseif ($statement instanceof QueryStatement) {
118-
$body .= self::INDENT . $statement->output() . PHP_EOL;
117+
$body .= self::INDENT . $statement->output($controller->prefix()) . PHP_EOL;
118+
$this->addImport($controller, 'App\\' . $this->determineModel($controller->prefix(), $statement->model()));
119119
}
120120

121121
$body .= PHP_EOL;
@@ -161,4 +161,17 @@ private function buildImports(Controller $controller)
161161
return 'use ' . $class . ';';
162162
}, $imports));
163163
}
164+
165+
private function determineModel(string $prefix, ?string $reference)
166+
{
167+
if (empty($reference) || $reference === 'id') {
168+
return Str::studly(Str::singular($prefix));
169+
}
170+
171+
if (Str::contains($reference, '.')) {
172+
return Str::studly(Str::before($reference, '.'));
173+
}
174+
175+
return Str::studly($reference);
176+
}
164177
}

src/Lexers/StatementLexer.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
use Blueprint\Models\Statements\DispatchStatement;
88
use Blueprint\Models\Statements\EloquentStatement;
99
use Blueprint\Models\Statements\FireStatement;
10-
use Blueprint\Models\Statements\RedirectStatement;
11-
use Blueprint\Models\Statements\SendStatement;
1210
use Blueprint\Models\Statements\QueryStatement;
11+
use Blueprint\Models\Statements\RedirectStatement;
1312
use Blueprint\Models\Statements\RenderStatement;
13+
use Blueprint\Models\Statements\SendStatement;
1414
use Blueprint\Models\Statements\SessionStatement;
1515
use Blueprint\Models\Statements\ValidateStatement;
16-
use Illuminate\Support\Facades\Redirect;
16+
use Illuminate\Support\Str;
1717

1818
class StatementLexer implements Lexer
1919
{
@@ -133,11 +133,24 @@ private function extractTokens(string $statement, int $limit = -1)
133133

134134
private function analyzeQuery($statement)
135135
{
136+
if ($statement === 'all') {
137+
return new QueryStatement('all');
138+
}
139+
136140
$found = preg_match('/^all:(\\S+)$/', $statement, $matches);
137141
if ($found) {
138-
return new QueryStatement('all', $matches[1]);
142+
return new QueryStatement('all', [$matches[1]]);
143+
}
144+
145+
if (Str::contains($statement, 'pluck:')) {
146+
return new QueryStatement('pluck', $this->extractTokens($statement));
147+
}
148+
149+
$found = preg_match('/\b(count|exists)\b/', $statement, $matches);
150+
if ($found) {
151+
return new QueryStatement($matches[1], $this->extractTokens(trim(str_replace($matches[1], '', $statement))));
139152
}
140153

141-
return new QueryStatement('get', '', $this->extractTokens($statement));
154+
return new QueryStatement('get', $this->extractTokens($statement));
142155
}
143156
}

src/Models/Statements/EloquentStatement.php

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,39 +28,48 @@ public function operation(): string
2828
{
2929
return $this->operation;
3030
}
31-
31+
3232
public function reference(): string
3333
{
3434
return $this->reference;
3535
}
3636

37-
public function output(string $context)
37+
public function output(string $controller_prefix, string $context): string
3838
{
39+
$model = $this->determineModel($controller_prefix);
40+
$code = '';
41+
3942
if ($this->operation() == 'save') {
4043
if ($context === 'store') {
41-
$code = "$" . Str::lower(Str::singular($this->reference()));
44+
$code = "$" . Str::lower($model);
4245
$code .= ' = ';
43-
$code .= Str::studly($this->reference());
46+
$code .= $model;
4447
$code .= '::create($request->all());';
4548
} else {
46-
$code = "$" . Str::lower(Str::singular($this->reference())) . '->save();';
49+
$code = "$" . Str::lower($model) . '->save();';
4750
}
4851
}
4952

5053
if ($this->operation() == 'find') {
5154
if ($this->usesQualifiedReference()) {
5255
$model = $this->extractModel();
53-
} else {
54-
// TODO: this needs to be a real model reference
55-
$model = 'Model';
5656
}
57-
$code = "$" . Str::lower(Str::singular($model));
57+
58+
$code = "$" . Str::lower($model);
5859
$code .= ' = ';
5960
$code .= $model;
6061
$code .= '::find($' . $this->columnName($this->reference()) . ');';
6162
}
6263

63-
// TODO: handle other operations: destroy
64+
if ($this->operation() === 'delete') {
65+
if ($this->usesQualifiedReference()) {
66+
$code = $this->extractModel();
67+
$code .= '::destroy($' . str_replace('.', '->', $this->reference()) . ');';
68+
} else {
69+
// TODO: only for certain contexts or no matter what given simple reference?
70+
$code = "$" . Str::lower($model) . '->delete();';
71+
}
72+
}
6473

6574
return $code;
6675
}
@@ -84,4 +93,13 @@ private function extractModel()
8493
{
8594
return Str::studly(Str::before($this->reference(), '.'));
8695
}
96+
97+
private function determineModel(string $prefix)
98+
{
99+
if (empty($this->reference()) || $this->reference() === 'id') {
100+
return Str::studly(Str::singular($prefix));
101+
}
102+
103+
return Str::studly($this->reference());
104+
}
87105
}

src/Models/Statements/QueryStatement.php

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,74 +14,76 @@ class QueryStatement
1414
private $operation;
1515

1616
/**
17-
* @var string
17+
* @var array
1818
*/
19-
private $reference;
19+
private $clauses;
2020

2121
/**
22-
* @var array
22+
* @var string
2323
*/
24-
private $clauses;
24+
private $model = null;
2525

26-
public function __construct(string $operation, string $reference, array $clauses = [])
26+
public function __construct(string $operation, array $clauses = [])
2727
{
2828
$this->operation = $operation;
29-
$this->reference = $reference;
3029
$this->clauses = $clauses;
30+
31+
if ($operation === 'all' && !empty($this->clauses())) {
32+
$this->model = Str::studly(Str::singular($this->clauses()[0]));
33+
}
3134
}
3235

3336
public function operation(): string
3437
{
3538
return $this->operation;
3639
}
3740

38-
public function reference(): string
39-
{
40-
return $this->reference;
41-
}
42-
43-
public function model(): string
41+
public function model(): ?string
4442
{
45-
return Str::studly(Str::singular($this->reference()));
43+
return $this->model;
4644
}
4745

4846
public function clauses()
4947
{
5048
return $this->clauses;
5149
}
5250

53-
public function output()
51+
public function output(string $controller): string
5452
{
53+
$model = $this->determineModel($controller);
54+
5555
if ($this->operation() === 'all') {
56-
return '$' . $this->reference() . ' = ' . $this->model() . '::all();';
56+
if (is_null($this->model())) {
57+
return '$' . Str::lower(Str::plural($model)) . ' = ' . $model . '::all();';
58+
} else {
59+
return '$' . Str::lower($this->clauses()[0]) . ' = ' . $this->model() . '::all();';
60+
}
5761
}
5862

5963
$methods = [];
60-
$pluck_field = null;
6164
foreach ($this->clauses as $clause) {
62-
[$method, $value] = explode(':', $clause);
65+
[$method, $argument] = explode(':', $clause);
6366

6467
if (in_array($method, ['where', 'order', 'pluck'])) {
65-
$value = $this->columnName($value);
68+
$column = $this->columnName($model, $argument);
6669
}
6770

6871
if ($method === 'where') {
69-
$methods[] = $method . '(' . "'{$value}', $" . $value . ')';
72+
$methods[] = $method . '(' . "'{$column}', $" . str_replace('.', '->', $argument) . ')';
7073
} elseif ($method === 'pluck') {
71-
$pluck_field = $value;
72-
$methods[] = "pluck('{$value}')";
74+
$pluck_field = $argument;
75+
$methods[] = "pluck('{$column}')";
7376
} elseif ($method === 'order') {
74-
$methods[] = "orderBy('{$value}')";
77+
$methods[] = "orderBy('{$column}')";
7578
} else {
76-
$methods[] = $method . '(' . $value . ')';
79+
$methods[] = $method . '(' . $argument . ')';
7780
}
7881
}
7982

80-
// TODO: leverage model/context...
81-
$model = 'Post';
82-
83-
if ($pluck_field) {
83+
if ($this->operation() === 'pluck') {
8484
$variable_name = $this->pluckName($pluck_field);
85+
} elseif ($this->operation() === 'count') {
86+
$variable_name = Str::lower($model) . '_count';
8587
} else {
8688
$variable_name = Str::lower(Str::plural($model));
8789
}
@@ -90,19 +92,22 @@ public function output()
9092

9193
$code .= implode('->', $methods);
9294

93-
if (!$pluck_field) {
94-
$code .= '->get()';
95+
if (in_array($this->operation(), ['get', 'count'])) {
96+
$code .= '->' . $this->operation() . '()';
9597
}
9698

9799
$code .= ';';
98100

99101
return $code;
100102
}
101103

102-
private function columnName($value)
104+
private function columnName($model, $value)
103105
{
104106
if (Str::contains($value, '.')) {
105-
return Str::after($value, '.');
107+
$reference = Str::before($value, '.');
108+
if (strcasecmp($model, $reference) === 0) {
109+
return Str::after($value, '.');
110+
}
106111
}
107112

108113
return $value;
@@ -111,10 +116,18 @@ private function columnName($value)
111116
private function pluckName(string $field)
112117
{
113118
if (Str::contains($field, '.')) {
114-
dump('here');
115119
return Str::lower(Str::plural(str_replace('.', '_', $field)));
116120
}
117121

118122
return Str::lower('Post' . '_' . Str::plural($field));
119123
}
124+
125+
private function determineModel(string $prefix)
126+
{
127+
if (empty($this->model())) {
128+
return Str::studly(Str::singular($prefix));
129+
}
130+
131+
return Str::studly($this->model());
132+
}
120133
}

src/Models/Statements/RedirectStatement.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
namespace Blueprint\Models\Statements;
55

66

7+
use Illuminate\Support\Str;
8+
79
class RedirectStatement
810
{
911
/**
@@ -42,6 +44,11 @@ public function output()
4244

4345
if ($this->data()) {
4446
$code .= ', [' . $this->buildParameters($this->data()) . ']';
47+
} elseif (Str::contains($this->route(), '.')) {
48+
[$model, $method] = explode('.', $this->route());
49+
if (in_array($method, ['edit', 'update', 'show', 'destroy'])) {
50+
$code .= sprintf(", ['%s' => $%s]", $model, $model);
51+
}
4552
}
4653

4754
$code .= ');';

src/Models/Statements/SendStatement.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ public function data(): array
4646
return $this->data;
4747
}
4848

49-
public function output() {
49+
public function output()
50+
{
5051
$code = 'Mail::';
5152

5253
if ($this->to()) {

src/Models/Statements/SessionStatement.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function operation(): string
2626
{
2727
return $this->operation;
2828
}
29-
29+
3030
public function reference(): string
3131
{
3232
return $this->reference;

tests/Feature/Lexers/ControllerLexerTest.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
use Blueprint\Lexers\ControllerLexer;
66
use Blueprint\Lexers\StatementLexer;
7-
use Blueprint\Models\Statements\QueryStatement;
8-
use Blueprint\Models\Statements\RenderStatement;
97
use PHPUnit\Framework\TestCase;
108

119
class ControllerLexerTest extends TestCase

0 commit comments

Comments
 (0)