Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.34% covered (success)
94.34%
50 / 53
83.33% covered (warning)
83.33%
5 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ViewGen
94.34% covered (success)
94.34%
50 / 53
83.33% covered (warning)
83.33%
5 / 6
26.12
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getViewName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBreadcrumbs
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
3
 genForm
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
16
 genIndex
75.00% covered (warning)
75.00%
9 / 12
0.00% covered (danger)
0.00%
0 / 1
4.25
 render
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace San\Crud\Generators;
4
5use Illuminate\View\Compilers\BladeCompiler;
6use San\Crud\Utils\NameUtils;
7use San\Crud\Utils\RouteUtils;
8use San\Crud\Utils\SchemaUtils;
9use San\Crud\Utils\TextUtils;
10
11class ViewGen extends BaseGen {
12    public function __construct(public array $tables, public ?string $routePrefix = null) {
13        parent::__construct($tables);
14    }
15
16    public function getViewName() {
17        return $this->getVarName();
18    }
19
20    public function getBreadcrumbs($template, $path) {
21        $index = 1;
22        $total = (count($this->tables) * 2) - 1;
23
24        foreach ($this->tables as $table) {
25            $tables[] = $table;
26
27            if (!empty($lastTables)) {
28                $lastTable = $lastTables[count($lastTables) - 1];
29                $href = RouteUtils::makeRoute(NameUtils::getRouteName($lastTables) . '.show', $this->getRawVars($lastTables), $this->routePrefix);
30                $anchorText = sprintf('%s #{{ $%s->id }}', NameUtils::titleCase($lastTable), NameUtils::getVariableName($lastTable));
31                $links[] = $this->render($template, $path, [], ['href' => "{{ $href }}", 'anchortext' => $anchorText, 'index' => $index++, 'total' => $total]);
32            }
33
34            $href = RouteUtils::makeRoute(NameUtils::getRouteName($tables) . '.index', $this->getRawVars(array_slice($tables, 0, -1)), $this->routePrefix);
35            $anchorText = NameUtils::titleCase($table);
36            $links[] = $this->render($template, $path, [], ['href' => "{{ $href }}", 'anchortext' => $anchorText, 'index' => $index++, 'total' => $total]);
37
38            $lastTables[] = $table;
39        }
40
41        return join("\n\t\t\t\t\t\t", $links ?? []);
42    }
43
44    public function genForm(string $template, string $path, array $replacements, bool $edit) {
45        $input = function ($f) use ($edit, $path) {
46            $type = (!empty($f->values) ? 'select' : (preg_match('/text/i', $f->type) ? 'textarea' : (preg_match('/bool/i', $f->type) ? 'boolean' : (preg_match('/json/i', $f->type) ? 'json' : 'input'))));
47            $val = $edit ? sprintf('@old(\'%s\', %s)', $f->id, $f->type === 'json' ? "json_encode(\$_var_->{$f->id})" : "\$_var_->{$f->id}") : sprintf('@old(\'%s\')', $f->id);
48            $inputType = preg_match('/int|double|float|decimal/i', $f->type) ? 'number' : (preg_match('/mail/i', $f->id) ? 'email' : (preg_match('/password/i', $f->id) ? 'password' : (preg_match('/datetime/i', $f->type) ? 'datetime-local' : (preg_match('/date/i', $f->type) ? 'date' : (preg_match('/time/i', $f->type) ? 'time' : 'text')))));
49            $vars = ['_id_' => $f->id, '_name_' => $f->name, '_enums_' => TextUtils::arrayExport($f->values ?? [], TRUE), '_val_' => $val, '_type_' => $inputType, '_required_' => $f->nullable ? '' : 'required'];
50
51            if (!empty($f->relation)) {
52                $type = 'related';
53                $vars['_related_'] = NameUtils::getVariableName($f->related_table);
54                $vars['_relateds_'] = NameUtils::getVariableNamePlural($f->related_table);
55                $vars['_readable_'] = SchemaUtils::firstHumanReadableField($f->related_table, 'id') ?: 'id';
56                $vars['_relatedroute_'] = RouteUtils::makeRoute($vars['_relateds_'] . '.create', [], $this->routePrefix);
57            }
58
59            return trim(strtr(file_get_contents("$path/inputs/$type.blade.php"), $vars));
60        };
61
62        $err = function ($f) {
63            return sprintf("@if(\$errors->has('%s'))\n\t\t\t<div class='error small text-danger'>{{\$errors->first('%s')}}</div>\n\t\t@endif", $f->id, $f->id);
64        };
65
66        return $this->render($template, $path, $replacements, ['input' => $input, 'err' => $err]);
67    }
68
69    public function genIndex(string $template, string $path = '', array $replacements = []) {
70        $display = function ($f) use ($path) {
71            if (!empty($f->relation)) {
72                if ($index = array_search($f->related_table, $this->parentTables())) {
73                    $tables = array_slice($this->parentTables(), 0, $index + 1);
74
75                    return sprintf('<a href="{{%s}}" class="text-dark">{{$_var_?->%s?->%s ?: "(blank)"}}</a>',
76                        RouteUtils::makeRoute(NameUtils::getRouteName($tables) . '.show', $this->getRawVars($tables), $this->routePrefix), $f->relation, SchemaUtils::firstHumanReadableField($f->related_table, 'id') ?? 'id');
77                } else {
78                    return sprintf('<a href="{{%s}}" class="text-dark">{{$_var_?->%s?->%s ?: "(blank)"}}</a>',
79                        RouteUtils::makeRoute(NameUtils::getRouteName($f->related_table) . '.show', "\$_var_->$f->id ?: 0", $this->routePrefix), $f->relation, SchemaUtils::firstHumanReadableField($f->related_table, 'id') ?? 'id');
80                }
81            } else {
82                $type = preg_match('/(json|boolean|text)/', $f->type) ? $f->type : 'string';
83                return trim(strtr(file_get_contents("$path/display/$type.blade.php"), ['_col_' => $f->id]));
84            }
85        };
86
87
88        return $this->render($template, $path, $replacements, ['display' => $display]);
89    }
90
91    protected function render($f, $path, $replacements, $vars) {
92        $fields = array_map(fn($f) => (object) array_merge($f, ['name' => preg_replace('/ Id$/', '', $f['name'])]), $this->getFillableFields(['user_id']));
93        $readable = $this->getFirstReadableField('id');
94        $vars = array_merge(['fields' => $fields, 'hasSoftDelete' => $this->hasSoftDeletes(), 'hasTimestamps' => $this->hasTimestamps(), 'render' => fn($f) => call_user_func_array([$this, 'render'], [$f, $path, $replacements, $vars])], (array) $vars);
95        $template = file_get_contents("$path/$f.blade.php");
96        $str = BladeCompiler::render($template, $vars);
97        $str = TextUtils::replaceBlanks($str, array_merge((array) $replacements, ['readable' => $readable]));
98
99        return $str;
100    }
101}