/** * Fetch the compiled template for a model * * @param string $template Path to template * @param string $className * * @return string Compiled template */ protected function getTemplate($template, $className) { $this->template = $this->file->get($template); $relationModelList = GeneratorsServiceProvider::getRelationsModelVarsList(GeneratorsServiceProvider::splitFields($this->cache->getFields(), true)); // Replace template vars $modelVars = GeneratorsServiceProvider::getModelVars($this->cache->getModelName()); $this->template = GeneratorsServiceProvider::replaceModelVars($this->template, $modelVars); $fields = $this->cache->getFields() ?: []; $fields = GeneratorsServiceProvider::splitFields(implode(',', $fields), SCOPED_EXPLODE_WANT_ID_RECORD); $this->template = GeneratorsServiceProvider::replaceTemplateLines($this->template, '{{translations:line}}', function ($line, $fieldVar) use($fields, $relationModelList) { $fieldTexts = []; foreach ($fields + ['id' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'] as $field => $type) { if (array_key_exists($field, $relationModelList)) { // add the foreign model translation $foreignName = $relationModelList[$field]['dash-model']; $foreignNameText = $relationModelList[$field]['Space Model']; $fieldTexts[] = str_replace($fieldVar, "'{$foreignName}' => '{$foreignNameText}',", $line); if (trim_suffix($field, "_id") !== $foreignName) { $foreignName = trim_suffix($field, "_id"); $foreignNameText = GeneratorsServiceProvider::getModelVars($foreignName)['Space Model']; $fieldTexts[] = str_replace($fieldVar, "'{$foreignName}' => '{$foreignNameText}',", $line); } } if (is_array($type) && ($bitset = hasIt($type, 'bitset', HASIT_WANT_PREFIX | HASIT_WANT_VALUE))) { $params = preg_match('/bitset\\((.*)\\)/', $bitset, $matches) ? $matches[1] : ''; if ($params === '') { $params = $field; } $params = explode(',', $params); foreach ($params as $param) { $bitFieldNameText = GeneratorsServiceProvider::getModelVars($param)['Space Model']; $fieldTexts[] = str_replace($fieldVar, "'{$param}' => '{$bitFieldNameText}',", $line); } } $modelVars = GeneratorsServiceProvider::getModelVars($field); $fieldNameTrans = $field !== Pluralizer::plural($field) ? $modelVars['Space Model'] : $modelVars['Space Models']; $fieldTexts[] = str_replace($fieldVar, "'{$field}' => '{$fieldNameTrans}',", $line); } sort($fieldTexts); return implode("\n", $fieldTexts) . "\n"; }); $this->template = $this->replaceStandardParams($this->template); return $this->template; }
protected function replaceLines($template, $modelVars) { $relationModelList = GeneratorsServiceProvider::getRelationsModelVarsList(GeneratorsServiceProvider::splitFields($this->cache->getFields(), true)); $fields = GeneratorsServiceProvider::splitFields($this->cache->getFields(), SCOPED_EXPLODE_WANT_ID_RECORD | SCOPED_EXPLODE_WANT_TEXT); $template = GeneratorsServiceProvider::replaceTemplateLines($template, '{{field:line}}', function ($line, $fieldVar) use($fields) { $fieldText = ''; foreach ($fields as $field => $type) { $fieldText .= str_replace($fieldVar, $field, $line) . "\n"; } if ($fieldText === '') { $fieldText = "''"; } return $fieldText; }); $template = GeneratorsServiceProvider::replaceTemplateLines($template, '{{field:line:bool}}', function ($line, $fieldVar) use($fields) { $fieldText = ''; foreach ($fields as $field => $type) { if (preg_match('/\\bboolean\\b/', $type)) { $fieldText .= str_replace('{{field:line:bool}}', $field, $line) . "\n"; } } return $fieldText; }); $template = GeneratorsServiceProvider::replaceTemplateLines($template, '{{field:line:nobool}}', function ($line, $fieldVar) use($fields) { $fieldText = ''; foreach ($fields as $field => $type) { if (!preg_match('/\\bboolean\\b/', $type)) { $fieldText .= str_replace('{{field:line:nobool}}', $field, $line) . "\n"; } } return $fieldText; }); // add only unique lines $template = GeneratorsServiceProvider::replaceTemplateLines($template, '{{relations:line}}', function ($line, $fieldVar) use($fields, $relationModelList) { // we don't need the marker $line = str_replace($fieldVar, '', $line); $fieldText = ''; $fieldTexts = []; foreach ($fields as $field => $type) { // here we override for foreign keys if (array_key_exists($field, $relationModelList)) { $modelVars = $relationModelList[$field]; // Replace template vars $text = GeneratorsServiceProvider::replaceModelVars($line, $modelVars, '{{relations:', '}}') . "\n"; if (array_search($text, $fieldTexts) === false) { $fieldText .= $text; $fieldTexts[] = $text; } } } return $fieldText; }); // add only unique lines $template = GeneratorsServiceProvider::replaceTemplateLines($template, '{{relations:line:with_model}}', function ($line, $fieldVar) use($fields, $relationModelList, $modelVars) { // we don't need the marker $line = str_replace($fieldVar, '', $line); $fieldText = ''; $fieldTexts = []; if ($modelVars) { // add model $text = GeneratorsServiceProvider::replaceModelVars($line, $modelVars, '{{relations:', '}}') . "\n"; if (array_search($text, $fieldTexts) === false) { $fieldText .= $text; $fieldTexts[] = $text; } } foreach ($fields as $field => $type) { // here we override for foreign keys if (array_key_exists($field, $relationModelList)) { $relationModelVars = $relationModelList[$field]; // Replace template vars $text = GeneratorsServiceProvider::replaceModelVars($line, $relationModelVars, '{{relations:', '}}') . "\n"; if (array_search($text, $fieldTexts) === false) { $fieldText .= $text; $fieldTexts[] = $text; } } } return $fieldText; }); if (strpos($template, '{{relations') !== false) { $relations = ''; $foreignModels = []; foreach ($fields as $field => $type) { if (array_key_exists($field, $relationModelList)) { $relationModelVars = $relationModelList[$field]; if (array_search($relationModelVars['camelModels'], $foreignModels) === false) { $foreignField = trim_suffix($field, "_id"); $foreignModels[] = $relationModelVars['camelModels']; $foreignFieldList = "'{$relationModelVars['name']}', '{$relationModelVars['id']}'"; $relations .= <<<PHP /** * @param \\{{app_namespace}}\\{$modelVars['CamelModel']} \${$modelVars['camelModel']} * * @return array {$relationModelVars['CamelModel']} */ public function {$relationModelVars['camelModels']}List({$modelVars['CamelModel']} \${$modelVars['camelModel']} = null) { // fill the foreign list for {$relationModelVars['CamelModel']} if (\${$modelVars['camelModel']} !== null) { \${$relationModelVars['camelModels']} = !\${$modelVars['camelModel']}->{$foreignField} ? [] : [ \${$modelVars['camelModel']}->{$foreignField}->{$relationModelVars['id']} => \${$modelVars['camelModel']}->{$foreignField}->{$relationModelVars['name']} ]; } else { \${$relationModelVars['camelModels']} = {$relationModelVars['CamelModel']}::query()->get([{$foreignFieldList}])->pluck({$foreignFieldList})->all(); } return \${$relationModelVars['camelModels']}; } PHP; } } } $template = str_replace('{{relations}}', $relations, $template); if ($relationModelList) { $relationsVars = []; foreach ($relationModelList as $fieldName => $relationModelVars) { foreach ($relationModelVars as $relationModel => $relationModelVar) { // append if (array_key_exists($relationModel, $relationsVars)) { $relationsVars[$relationModel] .= ", '{$relationModelVar}' => \${$relationModelVar}"; } else { $relationsVars[$relationModel] = "'{$relationModelVar}' => \${$relationModelVar}"; } } } $template = GeneratorsServiceProvider::replaceModelVars($template, $relationsVars, '{{relations:compact:', '}}'); } } if (strpos($template, '{{auto}}') !== false) { $relations = ''; foreach ($fields as $field => $type) { $options = scopedExplode(':', ['(' => ')', '[' => ']', '{' => '}'], $type, null); foreach ($options as $option) { if (str_starts_with($option, 'auto')) { $auto = substr($option, 5, -1); $relations .= <<<PHP \$input['{$field}'] = {$auto}; PHP; } } } $template = str_replace('{{auto}}', $relations, $template); } if (strpos($template, '{{bitset:line}}') !== false) { $template = GeneratorsServiceProvider::replaceTemplateLines($template, '{{bitset:line}}', function ($line, $fieldVar) use($fields, $modelVars) { $line = str_replace($fieldVar, '', $line); $text = ''; foreach ($fields as $field => $type) { if (preg_match('/\\bbitset\\b/', $type)) { $fieldModelVars = GeneratorsServiceProvider::getModelVars($field); $allVars = array_merge($modelVars, $fieldModelVars); $allVars['field'] = $field; $text .= GeneratorsServiceProvider::replaceModelVars($line, $allVars, '{{bitset:', '}}') . "\n"; } } return $text; }); } return $template; }
/** * Add Laravel methods, as string, * for the fields * * @param string $modelVars * * @param bool $disable * * @param bool $onlyBoolean * @param bool $noBoolean * @param bool $useOp * * @return string * @internal param $model */ public function makeFormElements($modelVars, $disable = false, $onlyBoolean = false, $noBoolean = false, $useOp = false, $filterRows = false) { $formMethods = []; $relationModelList = GeneratorsServiceProvider::getRelationsModelVarsList(GeneratorsServiceProvider::splitFields($this->cache->getFields(), true)); $fields = GeneratorsServiceProvider::splitFields($this->cache->getFields(), SCOPED_EXPLODE_WANT_ID_TYPE_OPTIONS | SCOPED_EXPLODE_WANT_TEXT); $models = $modelVars['models']; $model = $modelVars['model']; $camelModel = $modelVars['camelModel']; $CamelModel = $modelVars['CamelModel']; $narrowText = " input-narrow"; $dash_models = $modelVars['dash-models']; foreach ($fields as $name => $values) { $type = $values['type']; $options = $values['options']; $nameModelVars = GeneratorsServiceProvider::getModelVars($name); if (strpos($options, 'hidden') !== false) { continue; } $nullable = strpos($options, 'nullable') !== false; if (strpos($options, 'guarded') !== false) { if ($useOp) { $readonly = true ? "['readonly', " : '['; $readonlyHalf = '[true ? \'readonly\' : '; $readonlyClose = ']'; $disabled = true ? "'disabled', " : ''; } else { $readonly = $disable ? "['readonly', " : '['; $readonlyHalf = "[{$disable} ? 'readonly' : "; $readonlyClose = ']'; $disabled = $disable ? "'disabled', " : ''; } } else { if ($useOp) { $readonly = '[isViewOp($op) ? \'readonly\' : \'\','; $readonlyHalf = '[isViewOp($op) ? \'readonly\' : '; $readonlyClose = ']'; $disabled = 'isViewOp($op) ? \'disabled\' : \'\','; } else { $readonly = $disable ? "['readonly', " : '['; $readonlyHalf = "[{$disable} ? 'readonly' : "; $readonlyClose = ']'; $disabled = $disable ? "'disabled', " : ''; } } $limit = null; $useShort = false; if (str_contains($type, '[')) { if (preg_match('/([^\\[]+?)\\[(\\d+)(?:\\,\\d+)?\\]/', $type, $matches)) { $type = $matches[1]; // string $limit = $matches[2]; // 50{,...,} } } if (preg_match('/\\btextarea\\b/', $options)) { // treat it as text with multiple rows $type = 'text'; } $foreignTable = ''; if (preg_match('/\\btable\\(([^)]+)\\)\\b/', $options, $matches)) { // treat it as text with multiple rows $foreignTable = $matches[1]; } $is_bitset_field = preg_match('/\\bbitset\\b/', $options); if (($type === 'boolean' || $is_bitset_field) && $noBoolean) { continue; } if ($type !== 'boolean' && !$is_bitset_field && $onlyBoolean) { continue; } $trans_name = $name; $labelName = $trans_name; $labelGroup = $dash_models; $afterElement = ''; $afterElementFilter = ''; $wrapRow = !$onlyBoolean; $inputNarrow = GeneratorsServiceProvider::isFieldNumeric($type) || $type === 'string' && $limit < 32 ? $narrowText : ''; if ($is_bitset_field) { if ($filterRows) { $formMethods[] = <<<PHP @foreach({{app_namespace}}\\{$CamelModel}::\${$name}_bitset as \$type => \$flag) <td>{!! \\Form::select(\$type, ['' => ' ', '0' => '0', '1' => '1', ], Input::get(\$type), ['form' => 'filter-{$models}', 'class' => 'form-control', ]) !!}</td> @endforeach PHP; } else { if ($wrapRow) { $formMethods[] = <<<PHP @foreach({{app_namespace}}\\{$CamelModel}::\${$name}_bitset as \$type => \$flag) <div class="row"> <label> {!! Form::checkbox(\$type, 1, Input::old(\$type), [{$disabled}]) !!} @lang('{$labelGroup}.{$labelName}') </label> </div> @endforeach PHP; } else { $formMethods[] = <<<PHP @foreach({{app_namespace}}\\{$CamelModel}::\${$name}_bitset as \$type => \$flag) <label> {!! Form::checkbox(\$type, 1, Input::old(\$type), [{$disabled}]) !!} @lang('{$labelGroup}.{$labelName}') </label> @endforeach PHP; } } } else { switch ($type) { case 'mediumInteger': case 'smallInteger': case 'tinyInteger': $element = "{!! Form::input('number', '{$name}', Input::old('{$name}'), {$readonly}'class'=>'form-control{$inputNarrow}', 'placeholder'=>noEditTrans('{$dash_models}.{$trans_name}'), {$readonlyClose}) !!}"; $elementFilter = "{!! Form::input('number', '{$name}', Input::get('{$name}'), ['form' => 'filter-{$models}', 'class'=>'form-control{$inputNarrow}', 'placeholder'=>noEditTrans('{$dash_models}.{$trans_name}'), ]) !!}"; break; case 'bigInteger': case 'integer': if (array_key_exists($name, $relationModelList)) { // assume foreign key $afterElement = ""; $foreignModelVars = $relationModelList[$name]; $foreignModels = $foreignModelVars['camelModels']; $foreignmodels = $foreignModelVars['models']; $foreign_model = $foreignModelVars['snake_model']; $foreign_models = $foreignModelVars['snake_models']; $foreign_display = $foreignModelVars['name']; $plainName = trim_suffix($name, '_id'); $labelName = $plainName; $element = "{!! Form::select('{$name}', [0 => ''], \${$foreignModels}, Input::old('{$name}'), [{$disabled}'class' => 'form-control', ]) !!}"; if ($nullable) { $element .= "\n{!! Form::text('{$plainName}', \${$camelModel} ? (\${$camelModel}->{$plainName} ? \${$camelModel}->{$plainName}->{$foreign_display} : '') : '', {$readonlyHalf}'data-vsch_completion'=>'{$foreign_models}:{$foreign_display};id:{$name}','class' => 'form-control', {$readonlyClose}) !!}"; } else { $element .= "\n{!! Form::text('{$plainName}', \${$camelModel} ? \${$camelModel}->{$plainName}->{$foreign_display} : '', {$readonlyHalf}'data-vsch_completion'=>'{$foreign_models}:{$foreign_display};id:{$name}','class' => 'form-control', {$readonlyClose}) !!}"; } $elementFilter = "{!! Form::text('{$foreign_model}', Input::get('{$foreign_model}'), ['form' => 'filter-{$models}', 'data-vsch_completion'=>'{$foreign_models}:{$foreign_display};id:{$name}','class'=>'form-control', 'placeholder'=>noEditTrans('{$dash_models}.{$trans_name}'), ]) !!}"; if ($filterRows) { $afterElementFilter .= "{!! Form::hidden('{$name}', Input::old('{$name}'), ['form' => 'filter-{$models}', 'id'=>'{$name}']) !!}"; } else { $afterElementFilter .= "{!! Form::hidden('{$name}', Input::old('{$name}'), ['id'=>'{$name}']) !!}"; } //$labelName = $foreignModelVars['model']; //$labelGroup = $foreignModelVars['dash-models']; if ($useOp) { $afterElement .= "\n\t\n@if(\$op === 'create' || \$op === 'edit')"; } $afterElement .= "\n\t<div class='form-group col-sm-1'>\n\t\t\t<label> </label>\n\t\t\t<br>\n\t\t\t<a href=\"@route('{$foreignmodels}.create')\" @linkAsButton('warning')>@lang('messages.create')</a>\n</div>"; if ($useOp) { $afterElement .= "\n@endif"; } $element .= "\n\t\t\t" . $afterElementFilter; } else { $element = "{!! Form::input('number', '{$name}', Input::old('{$name}'), {$readonly}'class'=>'form-control{$inputNarrow}', 'placeholder'=>noEditTrans('{$dash_models}.{$trans_name}'), {$readonlyClose}) !!}"; $elementFilter = "{!! Form::input('number', '{$name}', Input::get('{$name}'), ['form' => 'filter-{$models}', 'class'=>'form-control{$inputNarrow}', 'placeholder'=>noEditTrans('{$dash_models}.{$trans_name}'), ]) !!}"; } break; case 'text': $limit = empty($limit) ? 256 : $limit; $rowAttr = (int) ($limit / 64) ?: 1; $element = "{!! Form::textarea('{$name}', Input::old('{$name}'), {$readonly}'class'=>'form-control', 'placeholder'=>noEditTrans('{$dash_models}.{$trans_name}'), 'rows'=>'{$rowAttr}', {$readonlyClose}) !!}"; $elementFilter = "{!! Form::text('{$name}', Input::get('{$name}'), ['form' => 'filter-{$models}', 'class'=>'form-control', 'placeholder'=>noEditTrans('{$dash_models}.{$trans_name}'), ]) !!}"; break; case 'boolean': $element = "{!! Form::checkbox('{$name}', 1, Input::old('{$name}'), [{$disabled}]) !!}"; $elementFilter = "{!! Form::select('{$name}', ['' => ' ', '0' => '0', '1' => '1', ], Input::get('{$name}'), ['form' => 'filter-{$models}', 'class' => 'form-control', ]) !!}"; $useShort = true; break; case 'date': case 'dateTime': $element = <<<HTML <div class="input-group input-group-sm date"> {!! Form::text('{$name}', Input::old('{$name}'), {$readonly}'class'=>'form-control{$inputNarrow}', 'placeholder'=>noEditTrans('{$dash_models}.{$trans_name}'), {$readonlyClose}) !!} <span class="input-group-addon"><span class="glyphicon glyphicon-calendar" aria-hidden="true"></span></span> </div> HTML; $elementFilter = <<<HTML <div class="input-group date"> {!! Form::text('{$name}', Input::get('{$name}'), ['form' => 'filter-{$models}', 'class'=>'form-control{$inputNarrow}', 'placeholder'=>noEditTrans('{$dash_models}.{$trans_name}'), ]) !!} <span class="input-group-addon"><span class="glyphicon glyphicon-calendar" aria-hidden="true"></span></span> </div> HTML; break; case 'decimal': case 'double': case 'float': case 'time': case 'string': default: $element = "{!! Form::text('{$name}', Input::old('{$name}'), {$readonly}'class'=>'form-control{$inputNarrow}', 'placeholder'=>noEditTrans('{$dash_models}.{$trans_name}'), {$readonlyClose}) !!}"; $elementFilter = "{!! Form::text('{$name}', Input::get('{$name}'), ['form' => 'filter-{$models}', 'class'=>'form-control{$inputNarrow}', 'placeholder'=>noEditTrans('{$dash_models}.{$trans_name}'), ]) !!}"; break; } if ($filterRows) { $afterElementFilter = $afterElementFilter ? "\n\t\t\t\t" . $afterElementFilter : $afterElementFilter; $frag = "\t\t\t\t<td>{$elementFilter}{$afterElementFilter}</td>"; } elseif ($useShort) { if ($wrapRow) { $frag = <<<EOT <div class="row"> <label> {$element} @lang('{$labelGroup}.{$labelName}') </label>{$afterElement} </div> EOT; } else { $frag = <<<EOT <label> {$element} @lang('{$labelGroup}.{$labelName}') </label>{$afterElement} EOT; } } else { if ($wrapRow) { $frag = <<<EOT <div class="row"> <div class="form-group col-sm-3"> <label for="{$name}">@lang('{$labelGroup}.{$labelName}'):</label> {$element} </div> </div> {$afterElement} EOT; } else { $frag = <<<EOT <div class="form-group"> <label for="{$name}">@lang('{$labelGroup}.{$labelName}'):</label> {$element}{$afterElement} </div> EOT; } } $formMethods[] = $frag; } } return implode(PHP_EOL, $formMethods); }
protected function replaceStandardParams($template) { $template = str_replace("{{app_namespace}}", trim_suffix(\App::getNamespace(), '\\'), $template); $template = str_replace("{{eol}}", "\n", $template); return $template; }