middleware('auth'); } public function index() { $contents = \App\Contents::where("kid","main")->orderBy("s","ASC")->get(); return view('admin.module-generator', compact('contents')); } public function generate(Request $request) { $request->validate([ 'title' => 'required|string|max:255', 'columns' => 'required|array', ]); $title = $request->title; $slug = Str::slug($title); $tableName = str_replace('-', '_', $slug); $modelName = Str::studly($slug); // 1. Create Migration File $timestamp = date('Y_m_d_His'); $migrationFilename = "{$timestamp}_create_{$tableName}_table.php"; $migrationPath = database_path("migrations/{$migrationFilename}"); $migrationContent = "id();\n"; foreach ($request->columns as $column) { $uiType = $column['type']; if ($uiType === 'separator') continue; // No column for separator $colName = Str::snake($column['name']); $dbType = 'string'; switch ($uiType) { case 'integer': $dbType = 'integer'; break; case 'decimal': $dbType = 'decimal'; break; case 'date': $dbType = 'date'; break; case 'datetime': $dbType = 'dateTime'; break; case 'time': $dbType = 'time'; break; case 'long-text': $dbType = 'longText'; break; case 'boolean': $dbType = 'boolean'; break; case 'multiple-choice': $dbType = 'text'; break; // Use text for multiple selection default: $dbType = 'string'; break; } if ($dbType == 'decimal') { $migrationContent .= " \$table->decimal('{$colName}', 15, 2)->nullable();\n"; } else { $migrationContent .= " \$table->{$dbType}('{$colName}')->nullable();\n"; } } $migrationContent .= " \$table->timestamps();\n \$table->softDeletes();\n });\n }\n\n public function down()\n {\n Schema::dropIfExists('{$tableName}');\n }\n}\n"; File::put($migrationPath, $migrationContent); // Run the specific migration Artisan::call('migrate', [ '--path' => "database/migrations/{$migrationFilename}", '--force' => true ]); // 2. Create Model $modelPath = app_path("Models/{$modelName}.php"); if (!File::exists($modelPath)) { $modelContent = "columns as $column) { $uiType = $column['type']; if ($uiType === 'separator') { $label = $column['label'] ?? 'Separator'; $relationDatasCode .= " 'separator_" . rand(100, 999) . "' => [\n 'type' => 'separator',\n 'label' => '{$label}',\n ],\n"; continue; } $colName = Str::snake($column['name']); $relationDatasCode .= " '{$colName}' => [\n 'type' => '{$uiType}',\n"; if ($uiType === 'select' || $uiType === 'multiple-choice') { $optionsStr = $column['options'] ?? ''; $optionsArr = array_map('trim', explode(',', $optionsStr)); $relationDatasCode .= " 'datas' => [\n"; foreach ($optionsArr as $opt) { if (empty($opt)) continue; $relationDatasCode .= " ['id' => '{$opt}', 'name' => '{$opt}'],\n"; } $relationDatasCode .= " ],\n"; if ($uiType === 'select') { $relationDatasCode .= " 'value' => 'id',\n"; } if ($uiType === 'multiple-choice') { $relationDatasCode .= " 'pattern' => '{name}',\n"; $relationDatasCode .= " 'seperator' => ',',\n"; } } elseif ($uiType === 'select-dropdown') { $source = $column['source'] ?? ''; $relationDatasCode .= " 'dataSource' => '{$source}',\n"; $relationDatasCode .= " 'datas' => [],\n"; $relationDatasCode .= " 'pattern' => '{name}',\n"; } $relationDatasCode .= " ],\n"; } $relationDatasCode .= "]"; $templateContent = str_replace('[[RELATION_DATAS]]', $relationDatasCode, $templateContent); File::put($viewPath, $templateContent); } } // 4. Handle Icon $iconName = $slug; if ($request->hasFile('icon')) { $request->file('icon')->move(base_path('assets/icons'), $iconName . '.png'); } // 5. Insert into types table $type = Types::where('slug', $slug)->first(); if (!$type) { $type = new Types(); $type->title = $title; $type->slug = $slug; $type->icon = $iconName; $type->enabled = 1; $type->full_control = "1"; $type->write = "1"; $type->read = "1"; $type->modify = "1"; $type->save(); } return redirect("admin/types/{$slug}")->with('success', 'Module generated successfully!'); } }